<!doctype html>
<html>
<head>
<meta charset='UTF-8'><meta name='viewport' content='width=device-width initial-scale=1'>
<title>EmbeddedNote</title><link href='https://fonts.loli.net/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext' rel='stylesheet' type='text/css' /><style type='text/css'>html {overflow-x: initial !important;}:root { --bg-color:#ffffff; --text-color:#333333; --select-text-bg-color:#B5D6FC; --select-text-font-color:auto; --monospace:"Lucida Console",Consolas,"Courier",monospace; --title-bar-height:20px; }
.mac-os-11 { --title-bar-height:28px; }
html { font-size: 14px; background-color: var(--bg-color); color: var(--text-color); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; }
body { margin: 0px; padding: 0px; height: auto; bottom: 0px; top: 0px; left: 0px; right: 0px; font-size: 1rem; line-height: 1.42857; overflow-x: hidden; background: inherit; tab-size: 4; }
iframe { margin: auto; }
a.url { word-break: break-all; }
a:active, a:hover { outline: 0px; }
.in-text-selection, ::selection { text-shadow: none; background: var(--select-text-bg-color); color: var(--select-text-font-color); }
#write { margin: 0px auto; height: auto; width: inherit; word-break: normal; overflow-wrap: break-word; position: relative; white-space: normal; overflow-x: visible; padding-top: 36px; }
#write.first-line-indent p { text-indent: 2em; }
#write.first-line-indent li p, #write.first-line-indent p * { text-indent: 0px; }
#write.first-line-indent li { margin-left: 2em; }
.for-image #write { padding-left: 8px; padding-right: 8px; }
body.typora-export { padding-left: 30px; padding-right: 30px; }
.typora-export .footnote-line, .typora-export li, .typora-export p { white-space: pre-wrap; }
.typora-export .task-list-item input { pointer-events: none; }
@media screen and (max-width: 500px) {
  body.typora-export { padding-left: 0px; padding-right: 0px; }
  #write { padding-left: 20px; padding-right: 20px; }
  .CodeMirror-sizer { margin-left: 0px !important; }
  .CodeMirror-gutters { display: none !important; }
}
#write li > figure:last-child { margin-bottom: 0.5rem; }
#write ol, #write ul { position: relative; }
img { max-width: 100%; vertical-align: middle; image-orientation: from-image; }
button, input, select, textarea { color: inherit; font: inherit; }
input[type="checkbox"], input[type="radio"] { line-height: normal; padding: 0px; }
*, ::after, ::before { box-sizing: border-box; }
#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p, #write pre { width: inherit; }
#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p { position: relative; }
p { line-height: inherit; }
h1, h2, h3, h4, h5, h6 { break-after: avoid-page; break-inside: avoid; orphans: 4; }
p { orphans: 4; }
h1 { font-size: 2rem; }
h2 { font-size: 1.8rem; }
h3 { font-size: 1.6rem; }
h4 { font-size: 1.4rem; }
h5 { font-size: 1.2rem; }
h6 { font-size: 1rem; }
.md-math-block, .md-rawblock, h1, h2, h3, h4, h5, h6, p { margin-top: 1rem; margin-bottom: 1rem; }
.hidden { display: none; }
.md-blockmeta { color: rgb(204, 204, 204); font-weight: 700; font-style: italic; }
a { cursor: pointer; }
sup.md-footnote { padding: 2px 4px; background-color: rgba(238, 238, 238, 0.7); color: rgb(85, 85, 85); border-radius: 4px; cursor: pointer; }
sup.md-footnote a, sup.md-footnote a:hover { color: inherit; text-transform: inherit; text-decoration: inherit; }
#write input[type="checkbox"] { cursor: pointer; width: inherit; height: inherit; }
figure { overflow-x: auto; margin: 1.2em 0px; max-width: calc(100% + 16px); padding: 0px; }
figure > table { margin: 0px; }
tr { break-inside: avoid; break-after: auto; }
thead { display: table-header-group; }
table { border-collapse: collapse; border-spacing: 0px; width: 100%; overflow: auto; break-inside: auto; text-align: left; }
table.md-table td { min-width: 32px; }
.CodeMirror-gutters { border-right: 0px; background-color: inherit; }
.CodeMirror-linenumber { user-select: none; }
.CodeMirror { text-align: left; }
.CodeMirror-placeholder { opacity: 0.3; }
.CodeMirror pre { padding: 0px 4px; }
.CodeMirror-lines { padding: 0px; }
div.hr:focus { cursor: none; }
#write pre { white-space: pre-wrap; }
#write.fences-no-line-wrapping pre { white-space: pre; }
#write pre.ty-contain-cm { white-space: normal; }
.CodeMirror-gutters { margin-right: 4px; }
.md-fences { font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; overflow: visible; white-space: pre; background: inherit; position: relative !important; }
.md-diagram-panel { width: 100%; margin-top: 10px; text-align: center; padding-top: 0px; padding-bottom: 8px; overflow-x: auto; }
#write .md-fences.mock-cm { white-space: pre-wrap; }
.md-fences.md-fences-with-lineno { padding-left: 0px; }
#write.fences-no-line-wrapping .md-fences.mock-cm { white-space: pre; overflow-x: auto; }
.md-fences.mock-cm.md-fences-with-lineno { padding-left: 8px; }
.CodeMirror-line, twitterwidget { break-inside: avoid; }
.footnotes { opacity: 0.8; font-size: 0.9rem; margin-top: 1em; margin-bottom: 1em; }
.footnotes + .footnotes { margin-top: 0px; }
.md-reset { margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: top; background: 0px 0px; text-decoration: none; text-shadow: none; float: none; position: static; width: auto; height: auto; white-space: nowrap; cursor: inherit; -webkit-tap-highlight-color: transparent; line-height: normal; font-weight: 400; text-align: left; box-sizing: content-box; direction: ltr; }
li div { padding-top: 0px; }
blockquote { margin: 1rem 0px; }
li .mathjax-block, li p { margin: 0.5rem 0px; }
li blockquote { margin: 1rem 0px; }
li { margin: 0px; position: relative; }
blockquote > :last-child { margin-bottom: 0px; }
blockquote > :first-child, li > :first-child { margin-top: 0px; }
.footnotes-area { color: rgb(136, 136, 136); margin-top: 0.714rem; padding-bottom: 0.143rem; white-space: normal; }
#write .footnote-line { white-space: pre-wrap; }
@media print {
  body, html { border: 1px solid transparent; height: 99%; break-after: avoid; break-before: avoid; font-variant-ligatures: no-common-ligatures; }
  #write { margin-top: 0px; padding-top: 0px; border-color: transparent !important; }
  .typora-export * { -webkit-print-color-adjust: exact; }
  .typora-export #write { break-after: avoid; }
  .typora-export #write::after { height: 0px; }
  .is-mac table { break-inside: avoid; }
}
.footnote-line { margin-top: 0.714em; font-size: 0.7em; }
a img, img a { cursor: pointer; }
pre.md-meta-block { font-size: 0.8rem; min-height: 0.8rem; white-space: pre-wrap; background: rgb(204, 204, 204); display: block; overflow-x: hidden; }
p > .md-image:only-child:not(.md-img-error) img, p > img:only-child { display: block; margin: auto; }
#write.first-line-indent p > .md-image:only-child:not(.md-img-error) img { left: -2em; position: relative; }
p > .md-image:only-child { display: inline-block; width: 100%; }
#write .MathJax_Display { margin: 0.8em 0px 0px; }
.md-math-block { width: 100%; }
.md-math-block:not(:empty)::after { display: none; }
.MathJax_ref { fill: currentcolor; }
[contenteditable="true"]:active, [contenteditable="true"]:focus, [contenteditable="false"]:active, [contenteditable="false"]:focus { outline: 0px; box-shadow: none; }
.md-task-list-item { position: relative; list-style-type: none; }
.task-list-item.md-task-list-item { padding-left: 0px; }
.md-task-list-item > input { position: absolute; top: 0px; left: 0px; margin-left: -1.2em; margin-top: calc(1em - 10px); border: none; }
.math { font-size: 1rem; }
.md-toc { min-height: 3.58rem; position: relative; font-size: 0.9rem; border-radius: 10px; }
.md-toc-content { position: relative; margin-left: 0px; }
.md-toc-content::after, .md-toc::after { display: none; }
.md-toc-item { display: block; color: rgb(65, 131, 196); }
.md-toc-item a { text-decoration: none; }
.md-toc-inner:hover { text-decoration: underline; }
.md-toc-inner { display: inline-block; cursor: pointer; }
.md-toc-h1 .md-toc-inner { margin-left: 0px; font-weight: 700; }
.md-toc-h2 .md-toc-inner { margin-left: 2em; }
.md-toc-h3 .md-toc-inner { margin-left: 4em; }
.md-toc-h4 .md-toc-inner { margin-left: 6em; }
.md-toc-h5 .md-toc-inner { margin-left: 8em; }
.md-toc-h6 .md-toc-inner { margin-left: 10em; }
@media screen and (max-width: 48em) {
  .md-toc-h3 .md-toc-inner { margin-left: 3.5em; }
  .md-toc-h4 .md-toc-inner { margin-left: 5em; }
  .md-toc-h5 .md-toc-inner { margin-left: 6.5em; }
  .md-toc-h6 .md-toc-inner { margin-left: 8em; }
}
a.md-toc-inner { font-size: inherit; font-style: inherit; font-weight: inherit; line-height: inherit; }
.footnote-line a:not(.reversefootnote) { color: inherit; }
.md-attr { display: none; }
.md-fn-count::after { content: "."; }
code, pre, samp, tt { font-family: var(--monospace); }
kbd { margin: 0px 0.1em; padding: 0.1em 0.6em; font-size: 0.8em; color: rgb(36, 39, 41); background: rgb(255, 255, 255); border: 1px solid rgb(173, 179, 185); border-radius: 3px; box-shadow: rgba(12, 13, 14, 0.2) 0px 1px 0px, rgb(255, 255, 255) 0px 0px 0px 2px inset; white-space: nowrap; vertical-align: middle; }
.md-comment { color: rgb(162, 127, 3); opacity: 0.8; font-family: var(--monospace); }
code { text-align: left; vertical-align: initial; }
a.md-print-anchor { white-space: pre !important; border-width: initial !important; border-style: none !important; border-color: initial !important; display: inline-block !important; position: absolute !important; width: 1px !important; right: 0px !important; outline: 0px !important; background: 0px 0px !important; text-decoration: initial !important; text-shadow: initial !important; }
.md-inline-math .MathJax_SVG .noError { display: none !important; }
.html-for-mac .inline-math-svg .MathJax_SVG { vertical-align: 0.2px; }
.md-math-block .MathJax_SVG_Display { text-align: center; margin: 0px; position: relative; text-indent: 0px; max-width: none; max-height: none; min-height: 0px; min-width: 100%; width: auto; overflow-y: hidden; display: block !important; }
.MathJax_SVG_Display, .md-inline-math .MathJax_SVG_Display { width: auto; margin: inherit; display: inline-block !important; }
.MathJax_SVG .MJX-monospace { font-family: var(--monospace); }
.MathJax_SVG .MJX-sans-serif { font-family: sans-serif; }
.MathJax_SVG { display: inline; font-style: normal; font-weight: 400; line-height: normal; zoom: 90%; text-indent: 0px; text-align: left; text-transform: none; letter-spacing: normal; word-spacing: normal; overflow-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; padding: 0px; margin: 0px; }
.MathJax_SVG * { transition: none 0s ease 0s; }
.MathJax_SVG_Display svg { vertical-align: middle !important; margin-bottom: 0px !important; margin-top: 0px !important; }
.os-windows.monocolor-emoji .md-emoji { font-family: "Segoe UI Symbol", sans-serif; }
.md-diagram-panel > svg { max-width: 100%; }
[lang="flow"] svg, [lang="mermaid"] svg { max-width: 100%; height: auto; }
[lang="mermaid"] .node text { font-size: 1rem; }
table tr th { border-bottom: 0px; }
video { max-width: 100%; display: block; margin: 0px auto; }
iframe { max-width: 100%; width: 100%; border: none; }
.highlight td, .highlight tr { border: 0px; }
mark { background: rgb(255, 255, 0); color: rgb(0, 0, 0); }
.md-html-inline .md-plain, .md-html-inline strong, mark .md-inline-math, mark strong { color: inherit; }
mark .md-meta { color: rgb(0, 0, 0); opacity: 0.3 !important; }
@media print {
  .typora-export h1, .typora-export h2, .typora-export h3, .typora-export h4, .typora-export h5, .typora-export h6 { break-inside: avoid; }
}
.md-diagram-panel .messageText { stroke: none !important; }
.md-diagram-panel .start-state { fill: var(--node-fill); }
.md-diagram-panel .edgeLabel rect { opacity: 1 !important; }
.md-require-zoom-fix foreignobject { font-size: var(--mermaid-font-zoom); }


.CodeMirror { height: auto; }
.CodeMirror.cm-s-inner { background: inherit; }
.CodeMirror-scroll { overflow: auto hidden; z-index: 3; }
.CodeMirror-gutter-filler, .CodeMirror-scrollbar-filler { background-color: rgb(255, 255, 255); }
.CodeMirror-gutters { border-right: 1px solid rgb(221, 221, 221); background: inherit; white-space: nowrap; }
.CodeMirror-linenumber { padding: 0px 3px 0px 5px; text-align: right; color: rgb(153, 153, 153); }
.cm-s-inner .cm-keyword { color: rgb(119, 0, 136); }
.cm-s-inner .cm-atom, .cm-s-inner.cm-atom { color: rgb(34, 17, 153); }
.cm-s-inner .cm-number { color: rgb(17, 102, 68); }
.cm-s-inner .cm-def { color: rgb(0, 0, 255); }
.cm-s-inner .cm-variable { color: rgb(0, 0, 0); }
.cm-s-inner .cm-variable-2 { color: rgb(0, 85, 170); }
.cm-s-inner .cm-variable-3 { color: rgb(0, 136, 85); }
.cm-s-inner .cm-string { color: rgb(170, 17, 17); }
.cm-s-inner .cm-property { color: rgb(0, 0, 0); }
.cm-s-inner .cm-operator { color: rgb(152, 26, 26); }
.cm-s-inner .cm-comment, .cm-s-inner.cm-comment { color: rgb(170, 85, 0); }
.cm-s-inner .cm-string-2 { color: rgb(255, 85, 0); }
.cm-s-inner .cm-meta { color: rgb(85, 85, 85); }
.cm-s-inner .cm-qualifier { color: rgb(85, 85, 85); }
.cm-s-inner .cm-builtin { color: rgb(51, 0, 170); }
.cm-s-inner .cm-bracket { color: rgb(153, 153, 119); }
.cm-s-inner .cm-tag { color: rgb(17, 119, 0); }
.cm-s-inner .cm-attribute { color: rgb(0, 0, 204); }
.cm-s-inner .cm-header, .cm-s-inner.cm-header { color: rgb(0, 0, 255); }
.cm-s-inner .cm-quote, .cm-s-inner.cm-quote { color: rgb(0, 153, 0); }
.cm-s-inner .cm-hr, .cm-s-inner.cm-hr { color: rgb(153, 153, 153); }
.cm-s-inner .cm-link, .cm-s-inner.cm-link { color: rgb(0, 0, 204); }
.cm-negative { color: rgb(221, 68, 68); }
.cm-positive { color: rgb(34, 153, 34); }
.cm-header, .cm-strong { font-weight: 700; }
.cm-del { text-decoration: line-through; }
.cm-em { font-style: italic; }
.cm-link { text-decoration: underline; }
.cm-error { color: red; }
.cm-invalidchar { color: red; }
.cm-constant { color: rgb(38, 139, 210); }
.cm-defined { color: rgb(181, 137, 0); }
div.CodeMirror span.CodeMirror-matchingbracket { color: rgb(0, 255, 0); }
div.CodeMirror span.CodeMirror-nonmatchingbracket { color: rgb(255, 34, 34); }
.cm-s-inner .CodeMirror-activeline-background { background: inherit; }
.CodeMirror { position: relative; overflow: hidden; }
.CodeMirror-scroll { height: 100%; outline: 0px; position: relative; box-sizing: content-box; background: inherit; }
.CodeMirror-sizer { position: relative; }
.CodeMirror-gutter-filler, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-vscrollbar { position: absolute; z-index: 6; display: none; }
.CodeMirror-vscrollbar { right: 0px; top: 0px; overflow: hidden; }
.CodeMirror-hscrollbar { bottom: 0px; left: 0px; overflow: hidden; }
.CodeMirror-scrollbar-filler { right: 0px; bottom: 0px; }
.CodeMirror-gutter-filler { left: 0px; bottom: 0px; }
.CodeMirror-gutters { position: absolute; left: 0px; top: 0px; padding-bottom: 30px; z-index: 3; }
.CodeMirror-gutter { white-space: normal; height: 100%; box-sizing: content-box; padding-bottom: 30px; margin-bottom: -32px; display: inline-block; }
.CodeMirror-gutter-wrapper { position: absolute; z-index: 4; background: 0px 0px !important; border: none !important; }
.CodeMirror-gutter-background { position: absolute; top: 0px; bottom: 0px; z-index: 4; }
.CodeMirror-gutter-elt { position: absolute; cursor: default; z-index: 4; }
.CodeMirror-lines { cursor: text; }
.CodeMirror pre { border-radius: 0px; border-width: 0px; background: 0px 0px; font-family: inherit; font-size: inherit; margin: 0px; white-space: pre; overflow-wrap: normal; color: inherit; z-index: 2; position: relative; overflow: visible; }
.CodeMirror-wrap pre { overflow-wrap: break-word; white-space: pre-wrap; word-break: normal; }
.CodeMirror-code pre { border-right: 30px solid transparent; width: fit-content; }
.CodeMirror-wrap .CodeMirror-code pre { border-right: none; width: auto; }
.CodeMirror-linebackground { position: absolute; left: 0px; right: 0px; top: 0px; bottom: 0px; z-index: 0; }
.CodeMirror-linewidget { position: relative; z-index: 2; overflow: auto; }
.CodeMirror-wrap .CodeMirror-scroll { overflow-x: hidden; }
.CodeMirror-measure { position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden; }
.CodeMirror-measure pre { position: static; }
.CodeMirror div.CodeMirror-cursor { position: absolute; visibility: hidden; border-right: none; width: 0px; }
.CodeMirror div.CodeMirror-cursor { visibility: hidden; }
.CodeMirror-focused div.CodeMirror-cursor { visibility: inherit; }
.cm-searching { background: rgba(255, 255, 0, 0.4); }
@media print {
  .CodeMirror div.CodeMirror-cursor { visibility: hidden; }
}


:root {
    --side-bar-bg-color: #fafafa;
    --control-text-color: #777;
}

@include-when-export url(https://fonts.loli.net/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext);

/* open-sans-regular - latin-ext_latin */
  /* open-sans-italic - latin-ext_latin */
    /* open-sans-700 - latin-ext_latin */
    /* open-sans-700italic - latin-ext_latin */
  html {
    font-size: 16px;
}

body {
    font-family: "Open Sans","Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
    color: rgb(51, 51, 51);
    line-height: 1.6;
}

#write {
    max-width: 860px;
  	margin: 0 auto;
  	padding: 30px;
    padding-bottom: 100px;
}

@media only screen and (min-width: 1400px) {
	#write {
		max-width: 1024px;
	}
}

@media only screen and (min-width: 1800px) {
	#write {
		max-width: 1200px;
	}
}

#write > ul:first-child,
#write > ol:first-child{
    margin-top: 30px;
}

a {
    color: #4183C4;
}
h1,
h2,
h3,
h4,
h5,
h6 {
    position: relative;
    margin-top: 1rem;
    margin-bottom: 1rem;
    font-weight: bold;
    line-height: 1.4;
    cursor: text;
}
h1:hover a.anchor,
h2:hover a.anchor,
h3:hover a.anchor,
h4:hover a.anchor,
h5:hover a.anchor,
h6:hover a.anchor {
    text-decoration: none;
}
h1 tt,
h1 code {
    font-size: inherit;
}
h2 tt,
h2 code {
    font-size: inherit;
}
h3 tt,
h3 code {
    font-size: inherit;
}
h4 tt,
h4 code {
    font-size: inherit;
}
h5 tt,
h5 code {
    font-size: inherit;
}
h6 tt,
h6 code {
    font-size: inherit;
}
h1 {
    font-size: 2.25em;
    line-height: 1.2;
    border-bottom: 1px solid #eee;
}
h2 {
    font-size: 1.75em;
    line-height: 1.225;
    border-bottom: 1px solid #eee;
}

/*@media print {
    .typora-export h1,
    .typora-export h2 {
        border-bottom: none;
        padding-bottom: initial;
    }

    .typora-export h1::after,
    .typora-export h2::after {
        content: "";
        display: block;
        height: 100px;
        margin-top: -96px;
        border-top: 1px solid #eee;
    }
}*/

h3 {
    font-size: 1.5em;
    line-height: 1.43;
}
h4 {
    font-size: 1.25em;
}
h5 {
    font-size: 1em;
}
h6 {
   font-size: 1em;
    color: #777;
}
p,
blockquote,
ul,
ol,
dl,
table{
    margin: 0.8em 0;
}
li>ol,
li>ul {
    margin: 0 0;
}
hr {
    height: 2px;
    padding: 0;
    margin: 16px 0;
    background-color: #e7e7e7;
    border: 0 none;
    overflow: hidden;
    box-sizing: content-box;
}

li p.first {
    display: inline-block;
}
ul,
ol {
    padding-left: 30px;
}
ul:first-child,
ol:first-child {
    margin-top: 0;
}
ul:last-child,
ol:last-child {
    margin-bottom: 0;
}
blockquote {
    border-left: 4px solid #dfe2e5;
    padding: 0 15px;
    color: #777777;
}
blockquote blockquote {
    padding-right: 0;
}
table {
    padding: 0;
    word-break: initial;
}
table tr {
    border-top: 1px solid #dfe2e5;
    margin: 0;
    padding: 0;
}
table tr:nth-child(2n),
thead {
    background-color: #f8f8f8;
}
table th {
    font-weight: bold;
    border: 1px solid #dfe2e5;
    border-bottom: 0;
    margin: 0;
    padding: 6px 13px;
}
table td {
    border: 1px solid #dfe2e5;
    margin: 0;
    padding: 6px 13px;
}
table th:first-child,
table td:first-child {
    margin-top: 0;
}
table th:last-child,
table td:last-child {
    margin-bottom: 0;
}

.CodeMirror-lines {
    padding-left: 4px;
}

.code-tooltip {
    box-shadow: 0 1px 1px 0 rgba(0,28,36,.3);
    border-top: 1px solid #eef2f2;
}

.md-fences,
code,
tt {
    border: 1px solid #e7eaed;
    background-color: #f8f8f8;
    border-radius: 3px;
    padding: 0;
    padding: 2px 4px 0px 4px;
    font-size: 0.9em;
}

code {
    background-color: #f3f4f4;
    padding: 0 2px 0 2px;
}

.md-fences {
    margin-bottom: 15px;
    margin-top: 15px;
    padding-top: 8px;
    padding-bottom: 6px;
}


.md-task-list-item > input {
  margin-left: -1.3em;
}

@media print {
    html {
        font-size: 13px;
    }
    table,
    pre {
        page-break-inside: avoid;
    }
    pre {
        word-wrap: break-word;
    }
}

.md-fences {
	background-color: #f8f8f8;
}
#write pre.md-meta-block {
	padding: 1rem;
    font-size: 85%;
    line-height: 1.45;
    background-color: #f7f7f7;
    border: 0;
    border-radius: 3px;
    color: #777777;
    margin-top: 0 !important;
}

.mathjax-block>.code-tooltip {
	bottom: .375rem;
}

.md-mathjax-midline {
    background: #fafafa;
}

#write>h3.md-focus:before{
	left: -1.5625rem;
	top: .375rem;
}
#write>h4.md-focus:before{
	left: -1.5625rem;
	top: .285714286rem;
}
#write>h5.md-focus:before{
	left: -1.5625rem;
	top: .285714286rem;
}
#write>h6.md-focus:before{
	left: -1.5625rem;
	top: .285714286rem;
}
.md-image>.md-meta {
    /*border: 1px solid #ddd;*/
    border-radius: 3px;
    padding: 2px 0px 0px 4px;
    font-size: 0.9em;
    color: inherit;
}

.md-tag {
    color: #a7a7a7;
    opacity: 1;
}

.md-toc { 
    margin-top:20px;
    padding-bottom:20px;
}

.sidebar-tabs {
    border-bottom: none;
}

#typora-quick-open {
    border: 1px solid #ddd;
    background-color: #f8f8f8;
}

#typora-quick-open-item {
    background-color: #FAFAFA;
    border-color: #FEFEFE #e5e5e5 #e5e5e5 #eee;
    border-style: solid;
    border-width: 1px;
}

/** focus mode */
.on-focus-mode blockquote {
    border-left-color: rgba(85, 85, 85, 0.12);
}

header, .context-menu, .megamenu-content, footer{
    font-family: "Segoe UI", "Arial", sans-serif;
}

.file-node-content:hover .file-node-icon,
.file-node-content:hover .file-node-open-state{
    visibility: visible;
}

.mac-seamless-mode #typora-sidebar {
    background-color: #fafafa;
    background-color: var(--side-bar-bg-color);
}

.md-lang {
    color: #b4654d;
}

.html-for-mac .context-menu {
    --item-hover-bg-color: #E6F0FE;
}

#md-notification .btn {
    border: 0;
}

.dropdown-menu .divider {
    border-color: #e5e5e5;
}

.ty-preferences .window-content {
    background-color: #fafafa;
}

.ty-preferences .nav-group-item.active {
    color: white;
    background: #999;
}


</style>
</head>
<body class='typora-export os-windows'>
<div id='write'  class=''><h1><a name="嵌入式处理器原理及应用by-chonpsk-202012）" class="md-header-anchor"></a><span>嵌入式处理器原理及应用（BY CHONPSK 2020/12）</span></h1><h2><a name="嵌入式硬件系统概述" class="md-header-anchor"></a><span>嵌入式硬件系统概述</span></h2><p>&nbsp;</p><ul><li><p><span>通用计算机与嵌入式系统对比</span></p><ul><li><figure><table><thead><tr><th><span>特征</span></th><th><span>通用计算机</span></th><th><span>嵌入式系统</span></th></tr></thead><tbody><tr><td><span>形式和类型</span></td><td><span>“看得见”的计算机。按其体系结构、运算速度和结构规模等因素分为大、中、小型机和微积。</span></td><td><span>“看不见”的计算机。形式多样，应用领域广泛，一般按应用分类。</span></td></tr><tr><td><span>组成</span></td><td><span>通用处理器、标准种线和外设。软件和硬件相对独立。</span></td><td><span>面向应用的嵌入式微处理器，总线和外部接口多集成在处理器内部。</span><br><span>软件与硬件式紧密集成在一起的</span></td></tr><tr><td><span>开发方式</span></td><td><span>开发平台和运行平台都是通用计算机</span></td><td><span>采用交叉开发方式，开发平台一般是通用计算机，运行平台是嵌入式系统。</span></td></tr><tr><td><span>二次开发性</span></td><td><span>应用程序可以重新编制</span></td><td><span>一般不能再编程</span></td></tr><tr><td><span>发展目标</span></td><td><span>变为功能电脑，普遍进入社会</span></td><td><span>变为专用电脑，实现“普及计算”</span></td></tr></tbody></table></figure></li></ul></li><li><p><span>嵌入式系统的特点</span></p><ul><li><p><span>形式多样、面向特定应用</span></p><ul><li><span>用于特定任务</span></li><li><strong><span>功耗低、体积小、集成度高</span></strong></li><li><span>os+app的一体化</span></li></ul></li><li><p><strong><span>得到多种类型处理器和处理器体系结构的支持</span></strong></p><ul><li><strong><span>可采用多种类型的处理器和处理器体系结构</span></strong></li><li><span>上千种mcu和几十种体系结构</span></li></ul></li><li><p><span>及其关注成本</span></p></li><li><p><strong><span>要求实时性和可靠性</span></strong></p><ul><li><span>大多数事实系统都是嵌入式系统</span></li><li><span>有硬实时和软实时</span></li><li><span>要求出错处理和自动复位功能，极端环境下可靠性设计尤为重要</span></li><li><span>硬件的看门狗定时器，软件的内存保护和重启动机制</span></li></ul></li><li><p><span>适应多种处理器、课间操、轻量型、实时可靠、可固化</span></p><ul><li><span>一般包括一个实时内核，其调度算法一般采用基于优先级的可抢占的调度算法。</span></li><li><span>高可靠嵌入式操作系统：时、空、数据隔离</span></li></ul></li><li><p><strong><span>开发需要专门工具和特殊方法</span></strong></p><ul><li><span>采用交叉开发的方式进行</span></li></ul></li></ul></li><li><p><span>嵌入式硬件系统的组成</span></p><ul><li><p><span>嵌入式系统的硬件是以嵌入式微处理器为核心，主要由嵌入式微处理器、总线、存储器、输入/输出接口和设备组成</span></p></li><li><p><span>嵌入式系统的软件是由初始化代码及驱动、嵌入式操作系统和应用程序等软件有机地结合在一起形成系统特定的一体化软件</span></p></li><li><p><span>其纳入是微处理器式嵌入式os的核心，其基础式通用的微处理器，但具有</span><strong><span>体积小、重量轻、成本低、功耗低、工作温度宽、抗电磁干扰、可靠性强</span></strong><span>等特点。在</span><strong><span>集成度、体系结构、指令集、性能、功耗管理和成本</span></strong><span>等方面都有适应嵌入式系统应用的特性。</span></p></li><li><p><span>总线：CPU与存储器和设备通信的极致，式计算机各部件之间传送数据、地址和控制信息的公共通道。：</span></p></li><li><p><span>总线：按相对于CPU位置划分</span></p><ul><li><span>片内总线/内部总线：连接CPU内部各主要功能部件，以构成SoC</span></li><li><span>片外总线：SoC与存储器（RAM/ROM）和I/O接口之间进行信息交换的通道</span></li></ul></li><li><p><span>总线：按功能和信号类型</span></p><ul><li><span>数据总线Dbus</span></li><li><span>地址总线：Abus</span></li><li><span>控制总线Cbus</span></li></ul></li><li><p><span>嵌入式系统存储器</span></p><ul><li><span>主存和外存（又称为辅存）</span></li><li><span>大多数嵌入式系统的代码和数据都存储在处理器可直接访问的存储空间即主存中，系统上电后在主存中的代码直接运行。主存储器的特点是速度快，一般采用ROM、EPROM、Nor Flash、SRAM、DRAM等存储器件</span></li><li><span>外存是处理器不能直接访问的存储器，用来存放各种信息，相对主存而言具有速度慢、价格低、容量大的特点</span></li><li><span>嵌入式系统中一般不采用硬盘而采用电子盘做外存，DOC\ANDFLASH</span></li></ul></li><li><p><span>io：嵌入式系统输入/输出接口及设备</span></p><ul><li><span>嵌入式系统的大多数输入/输出接口和部分设备已经集成在嵌入式微处理器中，输入/输出接口主要有中断控制器、DMA、串行和并行接口等，设备主要有定时器（Timers）、计数器（counters）、看门狗（watchdog timers）、RTC、UARTs、PWM（Pulse width modulator）、AD/DA、显示器、键盘和网络等</span></li></ul></li></ul></li><li><p><span>概述</span></p><ul><li><p><span>嵌入式微处理器的体系结构 ：可以分为冯•诺依曼（Von Neumann）结构或哈佛（Harvard）结构两大类。</span></p></li><li><p><img src="./Embedded_1.png" alt="两种结构" style="zoom:50%;" /></p><ul><li><figure><table><thead><tr><th><span>比较项目</span></th><th><span>CISC</span></th><th><span>RISC</span></th></tr></thead><tbody><tr><td><span>指令集</span></td><td><span>大量的混杂型指令集，有简单快速的指令，也有复杂的多周期指令，符合HLL</span></td><td><span>简单的单周期指令，在汇编指令方面有相应的CISC位代码指令</span></td></tr><tr><td><span>控制单元</span></td><td><span>微码</span></td><td><span>直接执行</span></td></tr><tr><td><span>寻址模式</span></td><td><span>复杂的寻址模式，支持内存到内存寻址</span></td><td><span>简单的寻址模式，仅允许LOAD和STORE指令存取内存，其它所有的操作都基于寄存器到寄存器</span></td></tr><tr><td><span>寄存器数目</span></td><td><span>寄存器较少</span></td><td><span>寄存器较多</span></td></tr><tr><td><span>性能</span></td><td><span>减少代码尺寸</span></td><td><span>使用流水线降低指令的执行周期数，增加代码尺寸</span></td></tr><tr><td><span>高级语言支持</span></td><td><span>硬件完成</span></td><td><span>软件完成</span></td></tr><tr><td><span>价格</span></td><td><span>有硬件完成部分软件功能，硬件复杂性能增加，芯片成本高</span></td><td><span>由软件完成硬件部分硬件功能，软件复杂性增加，芯片成本低。</span></td></tr></tbody></table></figure></li></ul></li></ul></li><li><p><span>嵌入式微处理器特点</span></p><ul><li><p><span>集成度</span></p><ul><li><p><span>集成了CPU核心、Cache、MMU、总线等部分外，还集成了各种外部接口和设备，如中断控制器、DMA、定时器、UART等。符合嵌入式系统的低成本和低功耗需求，一块单一的集成了大多数需要的功能块的芯片价格更低，功耗更少。 </span></p></li><li><p><span>组件的数目和种类是由它的市场定位决定的】</span></p></li><li><p><span>最普通的情况下，嵌入式微处理器包括</span></p><ul><li><strong><span>片内存储器：部分嵌入式微处理器</span></strong></li><li><span>外部存储器的控制器，外设接口(串口，并口)</span></li><li><span>LCD控制器：面向终端类应用的嵌入式微处理器</span></li><li><span>中断控制器，DMA控制器，协处理器</span></li><li><span>定时器，A/D、D/A转换器</span></li><li><span>多媒体加速器：当高级图形功能需要时</span></li><li><span>总线</span></li><li><span>其他标准接口或外设</span></li></ul></li></ul></li><li><p><span>体系结构</span></p><ul><li><p><span>算术格式</span></p><ul><li><span>低成本、低功耗限制，多数微处理器使用定点运算，即数值被表示为整数或在-1.0和+1.0之间的分数，避暑之表示为尾数和指数的浮点版本芯片更便宜</span></li><li><span>需要浮点运算时，可采用软件模拟的方式实现浮点运算，需要占用更多的处理器时间</span></li></ul></li><li><p><span>功能单元</span></p><ul><li><span>通常包括不止一个的功能单元，典型的是包含一个ALU、位移器和MAC，处理器通常用一条指令完成乘法操作</span></li></ul></li><li><p><span>流水线</span></p><ul><li><span>单周期执行指令，导致比较长的流水线</span></li></ul></li><li><p><span>指令集</span></p><ul><li><p><span>为满足应用领域的需要，嵌入式微处理器的指令集一般要针对特定领域的应用进行剪裁和扩充</span></p></li><li><p><span>需要DSP的数字处理功能，这些指令主要有：</span></p><ul><li><span>乘加(MAC)操作：一个周期中执行了一次乘法运算和一次加法运算。</span></li><li><span>SIMD类操作:允许使用一条指令进行多个并行数据流的计算</span></li><li><span>零开销的循环指令：用硬件方式减少了循环的开销。仅使用两条指令实现一个循环，一条是循环的开始并提供循环次数，另一条是循环体。</span></li><li><span>多媒体加速指令：像素处理、多边形，3D操作等指令</span></li></ul></li></ul></li></ul></li><li><p><span>性能</span></p><ul><li><p><span>低端（低价格，低性能）</span></p><ul><li><span>性能最多达到50MIPS，应用在对性能要求不高，但对</span><strong><span>价格和功耗</span></strong><span>有严格要求的应用系统中</span></li></ul></li><li><p><span>中档，低功耗</span></p><ul><li><span>性能：150MIPS以上，采用增加时钟频率、加深流水深度、增加Cache及一些额外的功能块来提高性能，并保持低功耗。</span></li></ul></li><li><p><span>高端</span></p></li><li><p><span>高端嵌入式微处理器用于高强度计算的应用，使用不同的方法来达到更高的并行度 </span></p><ul><li><strong><span>单指令执行乘法操作</span></strong><span>：</span><strong><span>通过加入额外的功能单元和扩展指令集，使许多操作能在一个单一的周期内并行执行</span></strong></li><li><strong><span>每个周期执行多条指令</span></strong><span>：桌面和服务器的超标量处理器都支持单周期多条指令执行，在嵌入式领域通常使用VLIW(very large instruction word)来实现，这样只需较少的硬件，总体价格会更低些。例如TI的TMS320C6201芯片，通过使用VLIW方法，能在每个周期同时执行8条独立的32位指令。</span></li><li><strong><span>使用多个处理器核</span></strong><span>：采用多处理器的方式满足应用系统的更高要求。一些嵌入式微处理器采用特殊的硬件支持多处理器。如TI的OMAP730包括了三个处理器核ARM9、ARM7、DSP。</span></li></ul></li></ul></li><li><p><span>功耗管理</span></p><ul><li><p><span>有功耗的限制（特别是电池供电的系统）不支持使用风扇等其他冷却设备</span></p><ul><li><span>降低工作电压：1.8v、1.2v~，而且这个数值一直在下降</span></li><li><span>提供不同的时钟频率：通过软件设置</span></li><li><span>关闭暂时不使用的功能块：如果某功能块在一个周期内不使用，就可以被完全关闭，以节约能量</span></li></ul></li><li><p><span>提供功耗管理机制</span></p><ul><li><span>运行模式：处理器处于全速运行状态下</span></li><li><span>待命模式：处理器不能执行指令，所有存储的信息时可用的，处理器能在几个周期内返回运行模式。</span></li><li><span>时钟关闭模式：时钟完全停止，要退出这个模式系统需要重新启动</span></li></ul></li><li><p><span>影响功耗的其他因素：</span></p><ul><li><span>总线：总线切换器，可采用特殊技术，使其功耗最小</span></li><li><span>存储器的大小（如果使用DRAM，它需要不断的刷新）。为了使功耗最小，总线和存储器要保持在应用系统可接受的最小规模。</span></li></ul></li></ul></li><li><p><span>成本</span></p><ul><li><p><span>为降低价格，需要在嵌入式微处理器设计者考虑不同的折衷方案</span></p><ul><li><span>处理器特点：功能块的数目、总线类型等。</span></li><li><span>片上存储器的大小</span></li><li><span>芯片的</span><strong><span>引脚数</span></strong><span>和</span><strong><span>封装形式</span></strong><span>：PQFP通常比BGA便宜</span></li><li><span>芯片大小：取决于制造的工艺水平</span></li></ul></li><li><p><span>代码密度：代码存储器的大小将影响价格，不同种类的处理器有不同的代码密度</span></p><ul><li><span>cisc芯片代码密度高，结构复杂</span></li><li><span>risc结构简单，代码密度低，指令集简单</span></li><li><span>VLIW代码密度最低，指令字倾向于采用多字节</span></li></ul></li></ul></li></ul></li><li><p><span>主流嵌入式微处理器</span></p><ul><li><span>许多不同体系</span></li><li><span>主流有ARM、MIPS、PowerPC、SH、X86等</span></li></ul></li><li><p><span>嵌入式系统的发展趋势</span></p><ul><li><p><span>面向应用领域的、高度集成的、以32位嵌入式微处理器为核心的SOC（System On Chip）成为应用主流</span></p></li><li><p><span>SoC给系统带来的高性能之外的更多重要好处：稳定性、体积、三日、功耗</span></p></li><li><p><span>嵌入式应用软件的开发需要强大的开发工具和操作系统的支持</span></p></li><li><p><span>嵌入式开发流程：</span></p><ul><li><span>Requirement Analysis</span></li><li><span>Software Design</span></li><li><span>Coding</span></li><li><span>Test</span></li><li><span>Release</span></li></ul></li><li><p><span>形成行业标准</span></p></li><li><p><strong><span>向新的嵌入式计算模型方向发展</span></strong><span> </span></p></li></ul></li></ul><p>&nbsp;</p><h2><a name="嵌入式处理器核心" class="md-header-anchor"></a><span>嵌入式处理器核心</span></h2><p><span>	</span></p><h3><a name="概述" class="md-header-anchor"></a><span>概述</span></h3><ul><li><p><span>ARM内核是一种32位RISC微处理器，具有功耗低、性价比高、代码密度高等三大特色。ARM处理器具有RISC体系结构的典型特征，同时具有以下特点</span></p><ul><li><span>每条数据处理指令字，都控制算术逻辑单元ALU和位移器，以使其获得最大利用率</span></li><li><strong><span>自动递增/递减寻址模式，优化程序中的循环</span></strong></li><li><span>同时L/S多条指令，增加数据吞吐量</span></li><li><span>所有指令可条件执行，增大执行吞吐量</span></li></ul></li></ul><h3><a name="经典arm-cpu-core体系结构" class="md-header-anchor"></a><span>经典ARM CPU Core体系结构</span></h3><ul><li><p><span>ARM7TDMI</span></p><ul><li><p><span>三级流水线</span></p></li><li><p><span>冯诺依曼架构</span></p></li><li><p><span>CPI约为1.9</span></p></li><li><p><span>Thumb架构扩展</span></p><ul><li><p><span>提供两个独立的指令集</span></p><ul><li><span>ARM指令，均为32位</span></li><li><span>Thumb指令，均为16位</span></li><li><span>两种运行状态，用来选择哪个指令集被执行</span></li></ul></li></ul></li><li><p><span>内核具有Debug扩展结构</span></p></li><li><p><span>EmbeddedICE逻辑</span></p></li><li><p><span>增强乘法器，配套乘法指令，支持32位和64位结果</span></p></li><li><p><span>指令流水线：3级流水线</span></p><ul><li><span>允许多个操作符同时处理，而非顺序执行。</span></li><li><span>PC指向正被取指的指令，而非正在执行的指令</span></li><li><span>fetch：从存储器中读取指令</span></li><li><span>decode：解码指令中用到的寄存器</span></li><li><span>execute：寄存器读（从寄存器Bank）位移及ALU操作寄存器写（到寄存器Bank）</span></li></ul></li></ul></li></ul><p>&nbsp;</p><h3><a name="arm编程模型" class="md-header-anchor"></a><span>ARM编程模型</span></h3><ul><li><p><span>数据宽度（类型）</span></p><ul><li><span>字节型数据（Byte）：数据宽度位8bits</span></li><li><span>半字节类型（HalfWord）：数据官渡位16bits，存取式必须以2字节对齐的方式</span></li><li><span>字数据类型（Word）：数据宽度位32bits，存器式必须以4字节对齐的方式</span></li></ul></li><li><p><span>工作状态和工作模式</span></p><ul><li><p><span>两种工作状态</span></p><ul><li><p><span>ARM:32位，执行字对准的ARM指令</span></p><ul><li><span>执行BX指令，并设置操作数寄存器的状态（位[0]）为0</span></li><li><span>进入异常时，将PC放入异常模式链接寄存器中，从异常向量地址开始执行也可进入ARM状态</span></li></ul></li><li><p><span>Thumb：16位，执行半字对准的Thumb指令</span></p><ul><li><span>执行BX指令，并设置操作数寄存器的状态（位【0】）为1</span></li><li><span>在Thumb状态进入异常(IRQ, FIQ, UNDEF, ABORT,SWI etc.)，当异常处理返回时自动转换到Thumb状态</span></li></ul></li></ul></li><li><p><span>ARM和Thumb之间状态的切换不影响处理器的模式或寄存器的内容</span></p></li><li><figure><table><thead><tr><th><span>处理器模式</span></th><th><span>说明</span></th></tr></thead><tbody><tr><td><span>用户模式(User)</span></td><td><span>正常程序执行模式，用于应用程序</span></td></tr><tr><td><span>异常模式(FIQ)</span></td><td><span>快速中断处理，用于支持高速数据传送或通道处理</span></td></tr><tr><td><span>异常模式(IRQ)</span></td><td><span>用于一般中断处理</span></td></tr><tr><td><span>异常模式(Suervisor)</span></td><td><span>特权模式，用于系统初始化或操作系统功能</span></td></tr><tr><td><span>异常模式(Abort)</span></td><td><span>存储器保护异常处理</span></td></tr><tr><td><span>异常模式(Undefined)</span></td><td><span>未定义指令异常处理</span></td></tr><tr><td><span>系统模式(System)</span></td><td><span>运行特权操作系统任务(ARM V4以上版本)</span></td></tr></tbody></table></figure></li><li><p><span>特权模式可以存取系统中的任何资源</span></p><ul><li><p><span>User模式（非特权模式）：</span></p><ul><li><strong><span>程序不能访问有些受保护的资源</span></strong></li><li><strong><span>只能通过异常的形式来改变CPU</span></strong><span> </span><strong><span>的当前运行模式</span></strong></li></ul></li><li><p><span>System模式（特权模式）</span></p><ul><li><span>与User模式的运行环境一样，但是它可以不受任何限制的访问任何资源，该模式主要用于运行系统中的一些特权任务</span></li></ul></li><li><p><span>FIQ,IRQ,Suprvisor,Abort,Undefined（特权模式）</span></p><ul><li><span>异常模式：主要是在外部中断或者程序执行非法操作时会触发</span></li></ul></li></ul></li></ul></li><li><p><span>寄存器</span></p><ul><li><p><span>arm处理器有37个寄存器</span></p><ul><li><span>31个通用寄存器：程序计数器、堆栈及其其他通用寄存器</span></li><li><span>6个状态寄存器</span></li></ul></li><li><p><span>这些寄存器不能同时看到</span></p></li><li><p><span>不同的处理器状态和工作模式确定哪些寄存器时对编程者时可见的</span></p></li><li><p><span>异常发生时伴随的模式切换意味着，被调用的异常处理程序会访问：</span></p><ul><li><span>自己的堆栈指针（SP_</span><span>&lt;</span><span>MODE&gt;）</span></li><li><span>自己的链接寄存器（LR_</span><span>&lt;</span><span>mode&gt;）</span></li><li><span>自己的备份程序状态寄存器（SPSR_</span><span>&lt;</span><span>MODE&gt;）</span></li><li><span>如果时FIQ异常处理，5个其它的通用状态寄存器（r8_FIQ to r12_FIQ）</span></li><li><span>其它寄存器和原来模式下的寄存器是相同的</span></li><li><span>ARM有37个寄存器，都是32位宽。有些寄存器的子集只能在相应模式被访问</span></li></ul></li><li><p><span>不同模式下堆栈指针的初始化</span></p><ul><li><p><span>各模式分组的堆栈指针寄存器是需要在系统初始化（即系统复位）时被设置好的，这样才能在进入不同的模式时自动切换使用不同的堆栈空间。初始化时需注意堆栈指针必须保持8字节对齐</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">;中断模式堆栈的设置</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">MSR</span> <span class="cm-keyword">CPSR_c</span>, <span class="cm-comment">#0x000000D2 &nbsp;  ;切换到中断模式</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">LDR</span> <span class="cm-variable">R1</span>, <span class="cm-tag">=</span> IrqStack</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">MOV</span> <span class="cm-variable">SP</span>, <span class="cm-variable">R1</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-comment">;设置中断模式堆栈指针</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">;快速中断模式堆栈的设置</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">MSR</span> <span class="cm-keyword">CPSR_c</span>, <span class="cm-comment">#0x000000D1 &nbsp;  ;切换到快速中断模式</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">LDR</span> <span class="cm-variable">R1</span>, <span class="cm-tag">=</span> FiqStack</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">MOV</span> <span class="cm-variable">SP</span>, <span class="cm-variable">R1</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-comment">;设置快速中断模式堆栈指针</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">;中止模式堆栈的设置</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 230px;"></div><div class="CodeMirror-gutters" style="display: none; height: 230px;"></div></div></div></pre></li><li><p><img src="./Embedded_2.png" referrerpolicy="no-referrer" alt="不同模式下堆栈指针的初始化"></p></li></ul></li><li><p><span>通用寄存器</span></p><ul><li><p><span>R0-R15，分为三大类</span></p><ul><li><p><span>没有对应影子寄存器：R0-R7</span></p><ul><li><span>所有模式下，R0-R7所对应的物理寄存器都是相同的 </span></li><li><span>这八个寄存器是真正意义上的通用寄存器，ARM体系结构中对它们没有作任何特殊的假设，它们的功能都是等同的</span></li><li><span>在中断或者异常处理程序中一般都需要对这几个寄存器进行保存</span></li></ul></li><li><p><span>有对应影子寄存器：R8-R14</span></p><ul><li><span>访问的物理寄存器取决于当前的处理器模式，若要访问特定的物理寄存器而不依赖当前的处理器模式，则要使用规定的名字</span></li><li><span>R8-R12各有两组物理寄存器：一组为FIQ模式，另一组是除FIQ以外的其他模式</span></li><li><span>R13-R14各有6个分组的物理寄存器，一个用于用户模式和系统模式，其他5个分别用于5种异常模式</span></li><li><span>R13（也被称为SP指针）被用作栈指针，通常在系统初始化时需要对所有模式下的SP指针赋值，当CPU在不同的模式时栈指针会被自动切换成相应模式下的值</span></li><li><span>R14有两个用途，一是在调用子程序时用于保存调用返回地址，二是在发生异常时用于保存异常返回地址</span></li></ul></li><li><p><span>程序计数器R15（pc）</span></p><ul><li><span>用作程序计数器(PC)，可以被读写</span></li><li><span>ARM state: bits [1:0]为0，bits[31:2]即为PC</span></li><li><span>THUMB state：bit [0]为0，bits[31:1]即为PC</span></li></ul></li></ul></li><li><p><span>影子寄存器是指该寄存器在不同的模式下对应的物理寄存器</span></p></li></ul></li><li><p><span>程序状态寄存器</span></p><ul><li><p><span>CPSR(当前程序状态寄存器)在所有的模式下都是可以读写的，它主要包含：</span></p><ul><li><span>条件标志</span></li><li><span>中断使能标志</span></li><li><span>当前处理器的模式</span></li><li><span>其他的一些状态和控制标志</span></li></ul></li></ul></li><li><p><span>arm寄存器的分配和使用</span></p><ul><li><p><span>寄存器的使用，在很大程度上与编译器有关系，不同的编译器对于不同体系结构处理器的寄存器的使用（比如函数参数传递和返回值）有其特定的规则</span></p></li><li><figure><table><thead><tr><th><span>寄存器编号</span></th><th><span>可选名字</span></th><th><span>ATPCS寄存器用法</span></th></tr></thead><tbody><tr><td><span>R0~R3</span></td><td><span>A1~A4</span></td><td><span>参数寄存器，在调用函数时，用来存放前四个函数参数和返回值（易失）</span></td></tr><tr><td><span>R4~R8</span></td><td><span>V1~V5</span></td><td><span>通用变量寄存器。（非易失）</span></td></tr><tr><td><span>R9</span></td><td><span>V6,SB</span></td><td><span>通用变量寄存器。在与读/写位置无关的编译情况下，用作基址寄存器（非易失）</span></td></tr><tr><td><span>R10</span></td><td><span>V7,SL</span></td><td><span>通用变量寄存器。在使用堆栈边界检查的编译情况下，r10保存堆栈边界的地址。（非易失）</span></td></tr><tr><td><span>R11</span></td><td><span>V8,FP</span></td><td><span>通用变量寄存器。在使用结构指针的情况下，必须保存这个寄存器中调用函数的变量值（非易失）</span></td></tr><tr><td><span>R12</span></td><td><span>IP</span></td><td><span>通用临时过渡寄存器（易失）</span></td></tr><tr><td><span>R13</span></td><td><span>SP</span></td><td><span>堆栈指针，指向满递减堆栈</span></td></tr><tr><td><span>R14</span></td><td><span>LR</span></td><td><span>链接寄存器，在函数调用时用以保存返回地址</span></td></tr><tr><td><span>R15</span></td><td><span>PC</span></td><td><span>程序计数器</span></td></tr></tbody></table></figure></li></ul></li></ul></li><li><p><span>中断与异常</span></p><ul><li><p><span>概述</span></p><ul><li><span>外部中断：由于CPU外部的原因而改变程序执行流程的过程，属于异步事件，又称为硬件中断。</span></li><li><span>软件中断（又称自陷）：表示通过处理器所拥有的软件指令、可预期地使处理器正在执行地程序地执行流程发生变化，以执行特定地程序。自陷使显式地事件，需要无条件地执行。典型地自陷指令如Motorola 68000系列中地Trap指令、ARM中地SWI指令和Intel80x86中地INT指令</span></li><li><span>异常：由CPU内部地原因（比如遇到非法指令）或外部地原因（比如访存地错误）引起的事件</span></li></ul></li><li><p><span>ARM处理器把上述三种事件都以异常模式来处理，并且都通过异常向量来响应 </span></p></li><li><p><span>当异常发生时CPU自动到指定的向量地址读取指令并且执行，即ARM的向量地址处存放的是一条指令（一般是一条跳转指令）</span></p><ul><li><span>在X86上，当有异常发生时CPU是到指定的向量地址读取要执行的程序的地址</span></li></ul></li><li><p><span>ARM CPU将引起异常的类型分为7种</span></p></li><li><p><span>异常的优先级</span></p><ul><li><p><span>有些异常会同时发生</span></p></li><li><p><span>异常被赋以了优先级，据此决定被响应的顺序</span></p><ul><li><img src="./Embedded_3.png" referrerpolicy="no-referrer" alt="异常的优先级"></li><li><span>在所有异常的入口，IRQ 中断被屏蔽 -只有重新被使能才可触发内核响应(如：中断嵌套处理)</span></li><li><span>在 FIQs 和 Reset 异常的入口，FIQ中断被屏蔽</span></li></ul></li></ul></li><li><p><span>异常响应过程</span></p><ul><li><p><span>拷贝CPSR寄存器的内容至对应模式下的 SPSR_</span><span>&lt;</span><span>mode&gt;寄存器中;</span></p></li><li><p><span>将返回地址保存到对应模式下的LR_</span><span>&lt;</span><span>mode&gt;寄存器中;</span></p></li><li><p><span>对 CPSR 寄存器的一些控制位进行设置：</span></p><ul><li><p><span>无论发生异常时处理器处于Thumb 状态还是ARM状态，响应异常后处理器都会切换到 ARM 状态，即CPSR[5]=0;</span></p></li><li><p><span>将模式位 CPSR[4:0]设置为被响应异常的模式编码</span></p></li><li><p><span>¢设置</span><strong><span>中断屏蔽位</span></strong><span>：如果异常模式为Reset 或 FIQ 则</span></p><ul><li><span>CPSR[6]=1       /</span><em><span>禁止快速中断</span></em><span>/</span></li><li><span>CPSR[7]=1       /</span><em><span>禁止正常中断</span></em><span>/</span></li></ul></li><li><p><span>将程序计数器（PC）设置为异常向量的地址</span></p></li></ul></li></ul></li><li><p><span>异常返回过程</span></p><ul><li><p><span>从异常处理程序返回时（执行特定的异常返回指令，需注意对于复位异常不需要返回），处理器执行下列动作</span></p><ul><li><span>将SPSR_</span><span>&lt;</span><span>mode&gt;中的内容恢复到CPSR中</span></li><li><span>将PC设置为LR_</span><span>&lt;</span><span>mode&gt; 的值</span></li></ul></li><li><p><span>同异常响应过程一样，上述过程只能在ARM状态下完成</span></p></li></ul></li><li><p><span>异常返回指令</span></p><ul><li><p><span>使用一条数据传输指令：具体的指令根据不同的异常而不同</span></p></li><li><p><span>在指令后需要加后缀 ‘ S ’ </span></p></li><li><p><span>将 PC 作为目标寄存器 </span></p><ul><li><p><span>在特权模式下，这不仅将 PC的值更新，而且将SPSR寄存器的内容加载到了CPSR</span></p></li><li><p><img src="./Embedded_4.png" referrerpolicy="no-referrer" alt="中断处理代码的开始和结束"></p></li><li><p><span>对于软中断和未定义指令异常返回</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">MOVS</span> <span class="cm-keyword">ps</span>,<span class="cm-variable-2">lr</span></span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 23px;"></div><div class="CodeMirror-gutters" style="display: none; height: 23px;"></div></div></div></pre></li></ul></li><li><p><span>对于 FIQ, IRQ 和指令预取异常返回</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">SUBS</span> <span class="cm-variable-2">pc</span>,<span class="cm-variable-2">lr</span>,<span class="cm-comment">#4</span></span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 23px;"></div><div class="CodeMirror-gutters" style="display: none; height: 23px;"></div></div></div></pre></li></ul></li><li><p><span>对于数据访问中止异常的返回</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">SUBS</span> <span class="cm-variable-2">pc</span>,<span class="cm-variable-2">lr</span>,<span class="cm-comment">#8</span></span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 23px;"></div><div class="CodeMirror-gutters" style="display: none; height: 23px;"></div></div></div></pre></li></ul></li><li><p><span>如果LR寄存器在压栈前已经被矫正，那么带 ^ 修饰符 LDM 指令 也可以用于返回</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">LDMFD</span> <span class="cm-variable">sp</span>!,<span class="cm-braket">{</span><span class="cm-variable-2">pc</span><span class="cm-braket">}</span>^</span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 23px;"></div><div class="CodeMirror-gutters" style="display: none; height: 23px;"></div></div></div></pre></li></ul></li></ul></li><li><p><span>返回地址</span></p><ul><li><p><span>校正异常返回地址的一大原因是ARM7的流水线</span></p><ul><li><span>为了向后兼容，更新的内核由相同的动作</span></li></ul></li><li><p><span>arm状态下：</span></p><ul><li><span>在异常发生时自动设置  LR_mode = PC - 4</span></li><li><span>异常处理程序可能需要矫正 LR_mode (取决于发生哪种异常) 以返回至正确的地址</span></li></ul></li><li><p><span>Thumb状态</span></p><ul><li><span>根据异常的不同，存储在LT_mode中的返回地址会被自动修正</span></li><li><span>这保证了ARM的返回指令会返回至正确的地址（不管异常发生时处于哪种状态）</span></li></ul></li></ul></li><li><p><span>从SWI和未定义指令异常返回</span></p><ul><li><p><span>异常时由当前指令产生的，在计算返回地址时还未更新PC值</span></p></li><li><figure><table><thead><tr><th><span>null</span></th><th><span>ARM</span></th><th><span>Thumb</span></th><th><span>null</span></th></tr></thead><tbody><tr><td><span>SWI*</span></td><td><span>PC-8</span></td><td><span>pc-4</span></td><td><span>在这里发生异常</span></td></tr><tr><td><span>XXX</span></td><td><span>pc-4</span></td><td><span>pc-2</span></td><td><span>lr=下一条指令</span></td></tr><tr><td><span>YYY</span></td><td><span>pc</span></td><td><span>pc</span></td><td>&nbsp;</td></tr></tbody></table></figure></li><li><p><span>返回地址为：MOVS pc,lr</span></p></li><li><p><span>注意：*标记表示从异常返回后即将执行指令</span></p></li></ul></li><li><p><span>从FIQ和IRQ异常返回</span></p><ul><li><span>异常在指令执行后被触发，在计算LR时PC已经被更新了</span></li><li><span>thumb寻址比arm少一半，因为指令长度少一半</span></li><li><span>返回指令是：SUBS pc,lr,#4</span></li></ul></li><li><p><span>从指令预取异常返回</span></p></li><li><p><span>从数据访问中止异常返回</span></p></li><li><p><span>异常返回地址的纠正</span></p><ul><li><figure><table><thead><tr><th><span>异常类型</span></th><th><span>正确的返回地址</span></th><th><span>地址纠正的原因</span></th></tr></thead><tbody><tr><td><span>复位</span></td><td><span>-</span></td><td><span>复位没有定义lr</span></td></tr><tr><td><span>数据中止</span></td><td><span>lr-8</span></td><td><span>指向导致数据中止异常的那条指令</span></td></tr><tr><td><span>FIQ</span></td><td><span>lr-4</span></td><td><span>FIQ处理程序的返回地址</span></td></tr><tr><td><span>IRQ</span></td><td><span>lr-4</span></td><td><span>IRQ处理程序的返回地址</span></td></tr><tr><td><span>指令预取中止</span></td><td><span>lr-4</span></td><td><span>指向导致预取指令中止异常的那条指令</span></td></tr><tr><td><span>SWI</span></td><td><span>lr</span></td><td><span>指向SWI指令的下一条指令</span></td></tr><tr><td><span>未定义指令</span></td><td><span>lr</span></td><td><span>指向未定义指令的下一条指令</span></td></tr></tbody></table></figure></li></ul></li></ul></li><li><p><span>异常向量表</span></p><ul><li><span>一段存储空间，包含了异常跳转地址</span></li><li><span>一种典型方法是使用文字池存储异常处理程序的地址，以后如果需要，可以改变它们</span></li></ul></li></ul></li><li><p><span>中断响应过程</span></p><ul><li><p><span>ARM CPU Core能响应两级的外部中断 —— FIQ 和 IRQ，这提供了非常基本的优先级分级功能。FIQ 中断比IRQ 中断的优先级更高，主要体现在以下几个方面</span></p><ul><li><span>当多个中断发生时，FIQ首先被处理</span></li><li><span>在 响应 FIQ 中断时屏蔽了 IRQ 中断 (和 FIQ中断)，直到FIQ中断处理程序完成，IRQ中断才会被处理</span></li></ul></li><li><p><span>以下特性能够让CPU Core能够尽快地响应FIQ中断</span></p><ul><li><span>FIQ 向量在异常向量表的最后，这样使FIQ处理程序可以直接从FIQ向量处开始，省去了跳转的时间开销</span></li><li><span>FIQ 模式下有五个额外的寄存器 (r8_FIQ to r12_FIQ)，对于这些寄存器在进入和推迟FIQ时无须保存和恢复，节省了时间;</span></li></ul></li><li><p><span>FIQ 中断源可以有多个, 但是为了最好的系统性能应该避免FIQ中断的嵌套，应该避免在 FIQ 中断处理程序内又有另一个异常发生</span></p></li></ul></li><li><p><span>中断处理</span></p><ul><li><p><span>ARM 有两级的外部中断 - FIQ 和 IRQ</span></p></li><li><p><span>但是绝大多数基于 ARM 的系统有两个以上的中断源!</span></p><ul><li><span>因此需要一个中断控制器 (通常是内存映射编址) 来控制中断信号如何进入 ARM 芯片</span></li><li><span>在很多系统中有些中断会比其它中断有更高的优先级 – 这就需要屏蔽那些有可能被处理但是优先级比它更低的中断</span></li><li><span>注意：一个中断处理程序必须包含清中断的代码</span></li><li><img src="./Embedded_5.png" referrerpolicy="no-referrer" alt="中断控制器"></li></ul></li><li><p><span>中断向量控制</span></p><ul><li><p><span>对于向量中断控制器( VIC ),v6提供了体系结构上的支持</span></p><ul><li><span>实现定义在以前版本上</span></li></ul></li><li><p><span>通过置位CP15 协处理器寄存器1上的 VE 位使能</span></p></li></ul></li><li><p><span>软中断调用</span></p><ul><li><span>用户代码调用软中断</span></li><li><span>软中断处理可由汇编部分和可选的c代码部分组成</span></li></ul></li></ul></li></ul><h3><a name="内存和io" class="md-header-anchor"></a><span>内存和I/O</span></h3><ul><li><p><span>ARM的寻址空间是线性的地址空间，为</span><span class="MathJax_SVG" tabindex="-1" style="font-size: 100%; display: inline-block;"><svg xmlns:xlink="http://www.w3.org/1999/xlink" width="9.12ex" height="2.461ex" viewBox="0 -956.9 3926.7 1059.4" role="img" focusable="false" style="vertical-align: -0.238ex;"><defs><path stroke-width="0" id="E1-MJMAIN-32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path><path stroke-width="0" id="E1-MJMAIN-33" d="M127 463Q100 463 85 480T69 524Q69 579 117 622T233 665Q268 665 277 664Q351 652 390 611T430 522Q430 470 396 421T302 350L299 348Q299 347 308 345T337 336T375 315Q457 262 457 175Q457 96 395 37T238 -22Q158 -22 100 21T42 130Q42 158 60 175T105 193Q133 193 151 175T169 130Q169 119 166 110T159 94T148 82T136 74T126 70T118 67L114 66Q165 21 238 21Q293 21 321 74Q338 107 338 175V195Q338 290 274 322Q259 328 213 329L171 330L168 332Q166 335 166 348Q166 366 174 366Q202 366 232 371Q266 376 294 413T322 525V533Q322 590 287 612Q265 626 240 626Q208 626 181 615T143 592T132 580H135Q138 579 143 578T153 573T165 566T175 555T183 540T186 520Q186 498 172 481T127 463Z"></path><path stroke-width="0" id="E1-MJMAIN-3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path><path stroke-width="0" id="E1-MJMAIN-34" d="M462 0Q444 3 333 3Q217 3 199 0H190V46H221Q241 46 248 46T265 48T279 53T286 61Q287 63 287 115V165H28V211L179 442Q332 674 334 675Q336 677 355 677H373L379 671V211H471V165H379V114Q379 73 379 66T385 54Q393 47 442 46H471V0H462ZM293 211V545L74 212L183 211H293Z"></path><path stroke-width="0" id="E1-MJMATHI-47" d="M50 252Q50 367 117 473T286 641T490 704Q580 704 633 653Q642 643 648 636T656 626L657 623Q660 623 684 649Q691 655 699 663T715 679T725 690L740 705H746Q760 705 760 698Q760 694 728 561Q692 422 692 421Q690 416 687 415T669 413H653Q647 419 647 422Q647 423 648 429T650 449T651 481Q651 552 619 605T510 659Q492 659 471 656T418 643T357 615T294 567T236 496T189 394T158 260Q156 242 156 221Q156 173 170 136T206 79T256 45T308 28T353 24Q407 24 452 47T514 106Q517 114 529 161T541 214Q541 222 528 224T468 227H431Q425 233 425 235T427 254Q431 267 437 273H454Q494 271 594 271Q634 271 659 271T695 272T707 272Q721 272 721 263Q721 261 719 249Q714 230 709 228Q706 227 694 227Q674 227 653 224Q646 221 643 215T629 164Q620 131 614 108Q589 6 586 3Q584 1 581 1Q571 1 553 21T530 52Q530 53 528 52T522 47Q448 -22 322 -22Q201 -22 126 55T50 252Z"></path></defs><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="matrix(1 0 0 -1 0 0)"><use xlink:href="#E1-MJMAIN-32" x="0" y="0"></use><g transform="translate(500,392)"><use transform="scale(0.707)" xlink:href="#E1-MJMAIN-32"></use><use transform="scale(0.707)" xlink:href="#E1-MJMAIN-33" x="500" y="0"></use></g><use xlink:href="#E1-MJMAIN-3D" x="1584" y="0"></use><use xlink:href="#E1-MJMAIN-34" x="2640" y="0"></use><use xlink:href="#E1-MJMATHI-47" x="3140" y="0"></use></g></svg></span><script type="math/tex">2^{23}=4G</script></p></li><li><p><span>Bytes 0 to 3存储第一个word，bytes 4  to 7 存储第二个word</span></p></li><li><p><span>ARM支持大端（Big-endian）和小端（Little-endian）的内存数据方式，可以通过硬件的方式设置（没有提供软件的方式）端模式</span></p></li><li><p><span>cpu与i/o设备之间的接口信息</span></p><ul><li><span>数据、状态、控制信息都是通过CPU的数据总线传送，存在I/O接口的不同端口中：数据、状态、控制端口</span></li></ul></li><li><p><span>内存和I/O – I/O端口编址方式</span></p><ul><li><p><span>I/O端口的地址与内存地址统一编址，即I/O单元与内存单元在同一地址空间</span></p></li><li><p><span>I/O端口与内存单元分开编址，即I/O单元与内存单元都有自己独立的地址空间</span></p></li><li><figure><table><thead><tr><th><span>null</span></th><th><span>存储器映射编址</span></th><th><span>I/O映射方式</span></th></tr></thead><tbody><tr><td><span>优点</span></td><td><span>可采用丰富的内存操作指令访问I/O单元</span><br><span>无需单独的I/O地址译码电路</span><br><span>无需专用的I/O指令</span></td><td><span>I/O单元不占用内存空间</span><br><span>I/O程序易读</span></td></tr><tr><td><span>缺点</span></td><td><span>外设占用内存空间</span><br><span>I/O程序不易读</span></td><td><span>I/O操作指令仅有单一的传送指令,I/O接口需有地址译码电路</span></td></tr><tr><td><span>举例</span></td><td><span>ARM中，I/O端口与内存单元统一编址</span></td><td><span>Intel 80X86系列，I/O端口与内存单元分开编址，I/O端口有自己独立的地址空间，其大小为64KB</span></td></tr></tbody></table></figure></li><li><p><span>ARM 的I/O端口都是内存映射的方式，即对I/O端口的访问与内存的访问的方式完全一样</span></p></li><li><p><span>通常将I/O所映射的存储系统标识为非高速缓存(uncachable)和非缓冲（unbufferable)</span></p></li></ul></li></ul><h2><a name="arm编程模型一内存空间和数据" class="md-header-anchor"></a><span>ARM编程模型一：内存空间和数据</span></h2><h3><a name="内存寻址空间和数据类型" class="md-header-anchor"></a><span>内存寻址空间和数据类型</span></h3><ul><li><p><span>ARM属于RISC体系，是32位读取/存储架构</span></p></li><li><p><span>ARM的寻址空间是线性的地址空间，典型的32位地址下，空间大小为</span><span class="MathJax_SVG" tabindex="-1" style="font-size: 100%; display: inline-block;"><svg xmlns:xlink="http://www.w3.org/1999/xlink" width="9.12ex" height="2.461ex" viewBox="0 -956.9 3926.7 1059.4" role="img" focusable="false" style="vertical-align: -0.238ex;"><defs><path stroke-width="0" id="E2-MJMAIN-32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path><path stroke-width="0" id="E2-MJMAIN-33" d="M127 463Q100 463 85 480T69 524Q69 579 117 622T233 665Q268 665 277 664Q351 652 390 611T430 522Q430 470 396 421T302 350L299 348Q299 347 308 345T337 336T375 315Q457 262 457 175Q457 96 395 37T238 -22Q158 -22 100 21T42 130Q42 158 60 175T105 193Q133 193 151 175T169 130Q169 119 166 110T159 94T148 82T136 74T126 70T118 67L114 66Q165 21 238 21Q293 21 321 74Q338 107 338 175V195Q338 290 274 322Q259 328 213 329L171 330L168 332Q166 335 166 348Q166 366 174 366Q202 366 232 371Q266 376 294 413T322 525V533Q322 590 287 612Q265 626 240 626Q208 626 181 615T143 592T132 580H135Q138 579 143 578T153 573T165 566T175 555T183 540T186 520Q186 498 172 481T127 463Z"></path><path stroke-width="0" id="E2-MJMAIN-3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path><path stroke-width="0" id="E2-MJMAIN-34" d="M462 0Q444 3 333 3Q217 3 199 0H190V46H221Q241 46 248 46T265 48T279 53T286 61Q287 63 287 115V165H28V211L179 442Q332 674 334 675Q336 677 355 677H373L379 671V211H471V165H379V114Q379 73 379 66T385 54Q393 47 442 46H471V0H462ZM293 211V545L74 212L183 211H293Z"></path><path stroke-width="0" id="E2-MJMATHI-47" d="M50 252Q50 367 117 473T286 641T490 704Q580 704 633 653Q642 643 648 636T656 626L657 623Q660 623 684 649Q691 655 699 663T715 679T725 690L740 705H746Q760 705 760 698Q760 694 728 561Q692 422 692 421Q690 416 687 415T669 413H653Q647 419 647 422Q647 423 648 429T650 449T651 481Q651 552 619 605T510 659Q492 659 471 656T418 643T357 615T294 567T236 496T189 394T158 260Q156 242 156 221Q156 173 170 136T206 79T256 45T308 28T353 24Q407 24 452 47T514 106Q517 114 529 161T541 214Q541 222 528 224T468 227H431Q425 233 425 235T427 254Q431 267 437 273H454Q494 271 594 271Q634 271 659 271T695 272T707 272Q721 272 721 263Q721 261 719 249Q714 230 709 228Q706 227 694 227Q674 227 653 224Q646 221 643 215T629 164Q620 131 614 108Q589 6 586 3Q584 1 581 1Q571 1 553 21T530 52Q530 53 528 52T522 47Q448 -22 322 -22Q201 -22 126 55T50 252Z"></path></defs><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="matrix(1 0 0 -1 0 0)"><use xlink:href="#E2-MJMAIN-32" x="0" y="0"></use><g transform="translate(500,392)"><use transform="scale(0.707)" xlink:href="#E2-MJMAIN-33"></use><use transform="scale(0.707)" xlink:href="#E2-MJMAIN-32" x="500" y="0"></use></g><use xlink:href="#E2-MJMAIN-3D" x="1584" y="0"></use><use xlink:href="#E2-MJMAIN-34" x="2640" y="0"></use><use xlink:href="#E2-MJMATHI-47" x="3140" y="0"></use></g></svg></span><script type="math/tex">2^{32}=4G</script></p></li><li><p><span>数据类型</span></p><ul><li><span>字节型数据（Byte）：数据宽度为8bits</span></li><li><span>半字数据类型（HalfWord）：数据宽度为16bits，存取时一般要求2字节对齐</span></li><li><span>字数据类型（Word）：数据宽度为32bits，存取时一般要求4字节对齐</span></li></ul></li></ul><p>&nbsp;</p><h3><a name="数据对齐" class="md-header-anchor"></a><span>数据对齐</span></h3><ul><li><span>在v6架构之前，数据访问都必须针对要访问的大小把访问地址进行对齐，没有对齐的地址将会导致出现“数据中止”异常(在数据存取或指令预取时都可能出现)</span></li><li><span>没有对齐的地址数据可以通过多个对齐地址数据移位/掩码操作来实现</span></li><li><span>ARM v6架构添加了新的硬件来支持未对齐的数据访问</span></li></ul><h3><a name="数据存储的大小端问题" class="md-header-anchor"></a><span>数据存储的大小端问题</span></h3><ul><li><p><span>大小端问题是指数据在计算机内存中的字节顺序问题，它决定了寄存器的内容和内存内容的格式关联</span></p></li><li><p><span>ARM寄存器是字宽，就是4字节。而内存寻址是按照字节顺序的</span></p></li><li><p><span>采用大端方式符合人类的正常思维，小端方式有利于计算机处理，无优劣之分</span></p></li><li><p><span>ARM支持大端（Big-endian）和小端（Little-endian）的内存数据方式，可以通过硬件的方式设置端模式，也可以通过软件的方式来设置（V6版本以上）</span></p></li><li><p><span>大端格式</span></p><ul><li><span>最低地址是该数据的地址（A）</span></li><li><span>最高有效字节（MSB，Most Significant Byte）放内存低地址（A）</span></li><li><span>最低有效字节（LSB，Least Significant Byte）放内存高地址（A+3）</span></li></ul></li><li><p><span>小端格式</span></p><ul><li><span>最低地址是该数据的地址（A）</span></li><li><span>最高有效字节（MSB，Most Significant Byte）放内存高地址（A+3）</span></li><li><span>最低有效字节（LSB，Least Significant Byte）放内存低地址（A）</span></li></ul></li><li><p><span>实例</span></p><ul><li><span>变量A：word A=0x f6 73 4b cd，在内存中的起始地址为0x b3 20 45 00</span></li><li><span>变量B：half word B=218，在内存中的起始地址为0x dd dd dd d0</span></li><li><img src="./Embedded_6.png" referrerpolicy="no-referrer" alt="大小端"></li></ul></li></ul><h2><a name="arm编程模型二状态模式和寄存器" class="md-header-anchor"></a><span>ARM编程模型二：状态模式和寄存器</span></h2><h3><a name="工作状态" class="md-header-anchor"></a><span>工作状态</span></h3><ul><li><p><span>大部分的ARM处理器都实现了两种指令集</span></p><ul><li><span>32位ARM指令集</span></li><li><span>16位 Thumb指令集</span></li></ul></li><li><p><span>ARM v6引入了新的指令集Thumb-2，能够提供了32位和16位的混合指令，在增强了灵活性的同时保持了代码高密度</span></p></li><li><p><span>ARM的两种工作状态</span></p><ul><li><span>ARM状态：执行32位ARM指令集</span></li><li><span>Thumb状态：执行16位Thumb指令集或v6及以后版本支持的Thumb-2指令集</span></li></ul></li><li><p><span>v4T~v6的工作模式</span></p><ul><li><span>有七种基本的操作模式：每一种模式只能访问自己的栈空间和不同的寄存器子集，有一些操作只能在特权模式下执行</span></li></ul></li></ul><p>&nbsp;</p><h2><a name="arm编程模型三指令集概述" class="md-header-anchor"></a><span>ARM编程模型三：指令集概述</span></h2><h3><a name="arm指令集" class="md-header-anchor"></a><span>ARM指令集</span></h3><ul><li><p><span>ARM是RISC架构，所有的指令长度都是32位 ，并且大多数指令都在一个单独周期内执行。主要特点包括：指令是条件执行的，内存访问使用Load /store架构</span></p></li><li><p><span>数据处理指令示例</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">SUB</span> &nbsp; &nbsp;<span class="cm-variable">r0</span>,<span class="cm-variable">r1</span>,<span class="cm-comment">#5</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">ADD</span> &nbsp; &nbsp;<span class="cm-variable">r2</span>,<span class="cm-variable">r3</span>,<span class="cm-variable">r3</span>,LSL <span class="cm-comment">#2</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">ANDS</span> &nbsp; <span class="cm-variable">r4</span>,<span class="cm-variable">r4</span>,<span class="cm-comment">#0x20</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">ADDEQ</span> &nbsp;<span class="cm-variable">r5</span>,<span class="cm-variable">r5</span>,<span class="cm-variable">r6</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 92px;"></div><div class="CodeMirror-gutters" style="display: none; height: 92px;"></div></div></div></pre></li></ul></li><li><p><span>分支指令示例</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">B</span> &lt;Label&gt;</span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 23px;"></div><div class="CodeMirror-gutters" style="display: none; height: 23px;"></div></div></div></pre></li></ul></li><li><p><span>内存访问指令示例</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">LDR</span> &nbsp; &nbsp;<span class="cm-variable">r0</span>,[<span class="cm-variable">r1</span>]</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">STRNEB</span> <span class="cm-variable">r2</span>,[<span class="cm-variable">r3</span>,<span class="cm-variable">r4</span>]</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">STMFD</span> &nbsp;<span class="cm-variable">sp</span>!,<span class="cm-braket">{</span><span class="cm-variable">r4</span>-<span class="cm-variable">r8</span>,<span class="cm-variable-2">lr</span><span class="cm-braket">}</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 69px;"></div><div class="CodeMirror-gutters" style="display: none; height: 69px;"></div></div></div></pre></li></ul></li></ul><h3><a name="thumb指令集" class="md-header-anchor"></a><span>Thumb指令集</span></h3><ul><li><span>Thumb是一个16位的指令集，是ARM指令集的功能子集，它对C代码的密度做了优化 (大约是ARM代码大小的65%)，提高了窄内存的性能</span></li><li><span>对大多数的Thumb指令而言，没有使用条件执行（标志一直都是置位的）， 源寄存器和目标寄存器是相同的，只使用了低端寄存器， 常量有大小的限制，没有使用内嵌桶型移位器</span></li><li><span>通过使用BX指令来切换ARM态和Thumb态</span></li><li><span>Thumb不是一个“常规”的指令集，一般由编译器生成，而不是手动编写代码</span></li></ul><p>&nbsp;</p><h3><a name="thumb-2指令集" class="md-header-anchor"></a><span>Thumb-2指令集</span></h3><ul><li><p><span>Thumb-2 主要在保留了完整的16位Thumb指令集的基础上，增加了32位指令实现了几乎所有的ARM指令集架构的功能</span></p><ul><li><span>ARM1156T2-S和Cortex 系列支持Thumb-2</span></li><li><span>Cortex-M3只支持Thumb-2</span></li></ul></li><li><p><span>设计目标:  以Thumb的指令密度达到ARM的性能</span></p><ul><li><span>编译器可以自动地选择16位和32位指令的混合，不需要手动选择，减少了剖析代码和理解执行方式的需求</span></li><li><span>可以访问ARM态的行为，包括处理异常、访问协处理器、高级数据处理等</span></li><li><span>条件执行方面，新增If-Then (IT) 指令，1-4条紧接指令可以条件性地执行</span></li></ul></li></ul><h3><a name="jazelle" class="md-header-anchor"></a><span>Jazelle</span></h3><ul><li><p><span>Jazelle使得ARM核可以执行8位的Java字节码。95%的字节码可以用硬件执行</span></p><ul><li><span>普通JVM:</span><span>	</span><span>0.7 Caffeinemarks/MHz</span></li><li><span>ARM9EJ:</span><span>	</span><span>5.5 Caffeinemarks/MHz</span></li></ul></li><li><p><span>功耗效率显著提高，相比ARM9E， ARM9EJ-S多了大约12K个额外的门电路，ARM JTEK (Java Technology Enabling Kit)提供了支持代码</span></p></li><li><p><span>当处理器在Jazelle态执行时，所有的指令都是8位宽，处理器进行字访问一次读4条指令</span></p></li></ul><p>&nbsp;</p><h3><a name="汇编指令集" class="md-header-anchor"></a><span>汇编指令集</span></h3><ul><li><p><span>ARM和Thumb指令集被设计用来得出最好的编译器输出，尤其是Thumb指令集</span></p></li><li><p><span>对于很多系统来说，设计上的主要关注被编译的代码上，指令集知识不太必要</span></p></li><li><p><span>但是在有些情况下，我们依然需要ARM指令集</span></p><ul><li><span>嵌入式系统需要初始化代码和中断例程</span></li><li><span>所有的系统都需要调试，并且很有可能是在汇编指令这一级的</span></li><li><span>通过编写汇编的处理例程可使系统的性能提高</span></li><li><span>ARM体系的有些特性对编译器是无效的</span></li></ul></li></ul><p>&nbsp;</p><p>&nbsp;</p><h2><a name="arm编程模型三arm-v4t指令集" class="md-header-anchor"></a><span>ARM编程模型三：ARM v4T指令集</span></h2><p>&nbsp;</p><h3><a name="arm-v4t目录" class="md-header-anchor"></a><span>ARM v4T目录</span></h3><ul><li><span>条件执行和标志位</span></li><li><span>数据处理指令</span></li><li><span>乘除法</span></li><li><span>分支指令</span></li><li><span>内存访问指令</span></li><li><span>SWP指令</span></li><li><span>软中断指令</span></li><li><span>PSR访问指令</span></li><li><span>协处理器访问</span></li></ul><h3><a name="正文" class="md-header-anchor"></a><span>正文</span></h3><h4><a name="条件执行和标志位" class="md-header-anchor"></a><span>条件执行和标志位</span></h4><ul><li><p><span>通过在指令后加上合适的条件标志位，ARM指令可以条件执行，通过减少前向的分支数目，增强了指令的代码密度和指令性能</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">CMP</span> &nbsp; &nbsp;<span class="cm-variable">r0</span>, <span class="cm-variable">r1</span><span class="cm-tab" role="presentation" cm-text="	">   </span><span class="cm-comment">; r0 - r1, 比较 r0 和 r1 并设置标志位</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" class="cm-tab-wrap-hack" style="padding-right: 0.1px;"><span class="cm-keyword">ADDGT</span> &nbsp;<span class="cm-variable">r2</span>, <span class="cm-variable">r2</span>, <span class="cm-comment">#1<span class="cm-tab" role="presentation" cm-text="	">   </span>; if r0&gt;r1 r2=r2+1 标志位保持不变 </span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" class="cm-tab-wrap-hack" style="padding-right: 0.1px;"><span class="cm-keyword">ADDLE</span> &nbsp;<span class="cm-variable">r3</span>, <span class="cm-variable">r3</span>, <span class="cm-comment">#1<span class="cm-tab" role="presentation" cm-text="	">   </span>; if r0&lt;=r1 r3=r3+1 标志位保持不变</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 69px;"></div><div class="CodeMirror-gutters" style="display: none; height: 69px;"></div></div></div></pre></li></ul></li><li><p><span>默认情况下，数据处理指令不会影响条件标志位，可在指令后加“s”后缀，以实现标志位的置位</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">loop</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-keyword">ADD</span> &nbsp; &nbsp;<span class="cm-variable">r2</span>, <span class="cm-variable">r2</span>, <span class="cm-variable">r3</span><span class="cm-tab" role="presentation" cm-text="	">   </span><span class="cm-comment">; r2=r2+r3 </span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" class="cm-tab-wrap-hack" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-keyword">SUBS</span> &nbsp; <span class="cm-variable">r1</span>, <span class="cm-variable">r1</span>, <span class="cm-comment">#0x01 <span class="cm-tab" role="presentation" cm-text="	">   </span>; r1 减1并设置标志位 <span class="cm-tab" role="presentation" cm-text="	">  </span> &nbsp; &nbsp;</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-keyword">BNE</span> &nbsp; &nbsp;<span class="cm-keyword">loop</span> <span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-comment">; 如果 Z 标志为0则分支跳转 </span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 92px;"></div><div class="CodeMirror-gutters" style="display: none; height: 92px;"></div></div></div></pre></li></ul></li><li><p><span>条件执行的作用</span></p><ul><li><span>减少执行指令，减少时钟周期，提高执行效率</span></li></ul></li><li><p><span>指令条件码</span></p><ul><li><img src="./Embedded_7.png" referrerpolicy="no-referrer" alt="后缀"></li></ul></li></ul><h4><a name="数据处理指令" class="md-header-anchor"></a><span>数据处理指令</span></h4><ul><li><p><span>由以下指令组成</span></p><ul><li><span>算术运算 :</span><span>	</span><span>ADD</span><span>	</span><span>ADC</span><span>	</span><span>SUB</span><span>	</span><span>SBC</span><span>	</span><span>RSB</span><span>	</span><span>RSC</span></li><li><span>逻辑运算 :</span><span>	</span><span>AND</span><span>	</span><span>ORR</span><span>	</span><span>EOR</span><span>	</span><span>BIC</span></li><li><span>比较运算 :</span><span>	</span><span>CMP</span><span>	</span><span>CMN</span><span>	</span><span>TST</span><span>	</span><span>TEQ</span></li><li><span>数据传送 :</span><span>	</span><span>MOV</span><span>	</span><span>MVN</span></li></ul></li><li><p><span>这些指令仅针对寄存器内的数据操作，不能使用内存数据</span></p></li><li><p><span>语法</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text="	">    </span>&lt;Operation&gt;<span class="cm-braket">{</span>&lt;cond&gt;<span class="cm-braket">}{</span>S<span class="cm-braket">}</span> Rd, Rn, Operand2</span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 23px;"></div><div class="CodeMirror-gutters" style="display: none; height: 23px;"></div></div></div></pre><ul><li><p><span>比较指令仅仅设置条件标志位，无需指定Rd</span></p><ul><li><span>CMP  r0, r3</span></li></ul></li><li><p><span>数据传送指令并不指定Rd</span></p><ul><li><span>MOV  r0, r1</span></li></ul></li><li><p><span>第2个操作数可以为一个寄存器或者一个立即数</span></p><ul><li><span>SUB  r0, r1, r2</span></li><li><span>AND  r1, r4, #0xFF</span></li></ul></li></ul></li></ul></li><li><p><span>第二个操作数通过桶型移位器传输到ALU，从而可附加移位操作。</span></p></li><li><p><span>主要的移位操作包括LSL, LSR, ASR, ROR, RRX</span></p></li><li><p><span>移位的值为0-31，可为以下的两种</span></p><ul><li><span>5位的无符号整数</span></li><li><span>其它寄存器的最低字节</span></li></ul></li><li><p><span>可以用来实现乘以一个常数</span></p><ul><li><span>ADD r0, r5, r5 LSL 1   -》  r0 = r5 x 3 </span></li></ul></li><li><p><span>主要的位移操作</span></p><ul><li><span>LSL(ASL)：逻辑或算术左移：相当于乘2</span></li><li><span>LSR：逻辑右移：相当于除2</span></li><li><span>ASR:算术右移：符号位不变，最低有效位进CF</span></li><li><span>ROR：循环右移：最低有效位旋转至最高有效位同时进CF</span></li><li><span>RRX：扩展的循环右移：CF填补空出的位，移出的位进CF</span></li><li><span>CF是指程序状态寄存器的C位</span></li></ul></li><li><p><span>第二操作数是立即数</span></p><ul><li><span>范围是在0-255的8位立即数，或者8位立即数循环右移偶数位得到的数</span></li><li><span>ARM 指令不能包含所有的32位立即数，因为ARM 指令都是32位定长的，在数据处理指令的格式中，第二个操作数有12位来对应</span></li><li><span>4 位的移位数乘以2组成了步长，范围在0－30的移位值</span></li><li><span>考虑，若机器码为0xe3a004ff，则其对应的指令为MOV r0, #4ff</span></li></ul></li><li><p><span>伪指令</span></p><ul><li><p><span>汇编器提供的伪指令:   LDR rd, =const</span></p></li><li><p><span>经汇编编译后结果将产生如下两种可能的结果之一:</span></p><ul><li><span>一条 MOV 或者  MVN 指令 </span></li><li><span>一条 PC相对寻址的LDR 指令，将立即数从literal pool (嵌入在代码中的常数域)里读出来</span></li></ul></li><li><p><span>推荐用这种方式将常数加载到寄存器</span></p></li><li><p><span>DCD也是伪指令，表示定义一个32位的数据</span></p></li></ul></li></ul><p>&nbsp;</p><h4><a name="乘除法" class="md-header-anchor"></a><span>乘除法</span></h4><ul><li><p><span>主要有两类乘法，分别对应产生32位和64位的运算结果</span></p></li><li><p><span>32位的这类乘法在 ARM7TDMI 会执行 2－ 5 时钟周期</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">MUL</span> <span class="cm-variable">r0</span>, <span class="cm-variable">r1</span>, <span class="cm-variable">r2</span><span class="cm-tab" role="presentation" cm-text="	">  </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-comment">; r0 = r1 * r2</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">MLA</span> <span class="cm-variable">r0</span>, <span class="cm-variable">r1</span>, <span class="cm-variable">r2</span>, <span class="cm-variable">r3</span><span class="cm-tab" role="presentation" cm-text="	">  </span><span class="cm-comment">; r0 = (r1 * r2) + r3</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 46px;"></div><div class="CodeMirror-gutters" style="display: none; height: 46px;"></div></div></div></pre></li></ul></li><li><p><span>64位的乘法提供了两种乘法指令：无符号和有符号乘法。对于这类指令他们有两个目标寄存器</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">[U|S]MULL <span class="cm-variable">r4</span>, <span class="cm-variable">r5</span>, <span class="cm-variable">r2</span>, <span class="cm-variable">r3</span> <span class="cm-comment">; r5:r4 = r2 * r3</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">[U|S]MLAL <span class="cm-variable">r4</span>, <span class="cm-variable">r5</span>, <span class="cm-variable">r2</span>, <span class="cm-variable">r3</span> <span class="cm-comment">; r5:r4 = (r2 * r3) + r5:r4</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 46px;"></div><div class="CodeMirror-gutters" style="display: none; height: 46px;"></div></div></div></pre></li></ul></li><li><p><span>大多数的低端ARM核不提供整数除法指令，除法操作由c的库函数或者移位操作实现。</span></p></li></ul><p>&nbsp;</p><h4><a name="分支指令" class="md-header-anchor"></a><span>分支指令</span></h4><ul><li><p><span>分支跳转指令的格式:   B{L}{</span><cond><span>} label</span></p></li><li><p><span>子函数调用可加上 {L}实现</span></p></li><li><p><span>在指令编码中，存在一个 24 位的地址域。在执行时它被左移两位 (因为 ARM 指令是字对齐的)，产生一个26位的偏移地址，由此可知跳转的范围大体在-32MB～+32MB之间</span></p></li><li><p><span>执行分支指令会引起流水线清空</span></p></li><li><p><span>子程序调用</span></p><ul><li><p><span>实现一个传统的子程序调用需要两个步骤</span></p><ul><li><span>保存返回地址</span></li><li><span>跳转到子程序的首地址</span></li></ul></li><li><p><span>这些步骤可以由BL指令完成，返回地址被保存在链接寄存器 (lr/r14)，分支跳转范围是+/- 32MB </span></p></li><li><p><span>重新加载LR寄存器的内容至PC寄存器即可实现返回</span></p></li></ul></li></ul><h4><a name="内存访问指令" class="md-header-anchor"></a><span>内存访问指令</span></h4><ul><li><p><span>单寄存器的数据传输指令</span></p><ul><li><figure><table><thead><tr><th><span>指令</span></th><th><span>功能</span></th></tr></thead><tbody><tr><td><span>LDR/STR</span></td><td><span>加载/存储字的操作</span></td></tr><tr><td><span>LDRB/STRB</span></td><td><span>加载/存储字节的操作</span></td></tr><tr><td><span>LDRH/STRH</span></td><td><span>加载/存储半字的操作</span></td></tr><tr><td><span>LDRSB</span></td><td><span>有符号的字节加载</span></td></tr><tr><td><span>LDRSH</span></td><td><span>有符号的半字加载</span></td></tr></tbody></table></figure></li><li><p><span>要求存储系统必须支持所有的访问尺寸</span></p></li><li><p><span>语法</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">LDR<span class="cm-braket">{</span>&lt;cond&gt;<span class="cm-braket">}{</span>&lt;size&gt;<span class="cm-braket">}</span> Rd, &lt;address&gt;</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">STR<span class="cm-braket">{</span>&lt;cond&gt;<span class="cm-braket">}{</span>&lt;size&gt;<span class="cm-braket">}</span> Rd, &lt;address&gt;</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 46px;"></div><div class="CodeMirror-gutters" style="display: none; height: 46px;"></div></div></div></pre></li></ul></li><li><p><span>举例  LDREQB</span></p></li></ul></li><li><p><span>内存寻址方式</span></p><ul><li><p><span>被LDR/STR指令访问的地址通过一个基址寄存器和一个偏移量来指定</span></p></li><li><p><span>对于字和无符号的字节访问, 偏移量可以为</span></p><ul><li><span>一个无符号的12位立即数 (0-4095)</span></li><li><span>寄存器, 还可附加移位操作</span></li></ul></li><li><p><span>对于半字和有符号的字节访问, 偏移量可以为一个8位的立即数 (0 - 255)或一个寄存器 (不可以被移位)</span></p></li><li><p><span>基址寄存器的地址可加也可减</span></p></li></ul></li><li><p><span>前序和后序寻址</span></p><ul><li><p><span>前序寻址: STR r0, [r1, #12]</span></p><ul><li><span>自动更新基址寄存器形式: STR r0,[r1,#12]!</span></li><li><span>寻址后r1不变</span></li></ul></li><li><p><span>后序寻址: STR r0, [r1], #12</span></p><ul><li><span>寻址后r1更新为当前加上偏移量的值</span></li></ul></li></ul></li><li><p><span>批量加载/存储指令</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">&lt;LDM|STM&gt;<span class="cm-braket">{</span>&lt;cond&gt;<span class="cm-braket">}</span>&lt;addressing_mode&gt; Rb<span class="cm-braket">{</span>!<span class="cm-braket">}</span>, &lt;register list&gt;</span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 23px;"></div><div class="CodeMirror-gutters" style="display: none; height: 23px;"></div></div></div></pre></li></ul></li><li><p><span>用LDR指令实现跳转</span></p><ul><li><span>ARM的分支指令跳转范围局限于 ±32MB，然而可通过直接将分支的地址加载到PC中实现跳转</span></li><li><span>为了简单起见,ARM汇编器提供了这样的伪指令，该伪指令实现了在 4GB 地址空间的任意跳转</span></li></ul></li></ul><h4><a name="swp指令" class="md-header-anchor"></a><span>SWP指令</span></h4><ul><li><p><span>用于在内存和寄存器之间传送一个字节或字的原子操作（不可被打断），先读取内存后写内存</span></p></li><li><p><span>语法</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">SWP<span class="cm-braket">{</span>&lt;cond&gt;<span class="cm-braket">}{</span>B<span class="cm-braket">}</span> Rd, Rm, [Rn]</span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 23px;"></div><div class="CodeMirror-gutters" style="display: none; height: 23px;"></div></div></div></pre></li></ul></li><li><p><span>可用于实现Flag，但不能由ARMCC汇编得到，只能由汇编指令实现</span></p></li><li><p><span>功能：引起了一个异常自陷， 跳转到软中断异常向量</span></p></li><li><p><span>软中断处理例程检查软中断号以决定如何处理该号中断</span></p></li><li><p><span>通过软中断这种机制, 操作系统可以实现一个特权操作集合，它们可被用户模式下的应用代码调用</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">语法: &nbsp;  SWI<span class="cm-braket">{</span>&lt;cond&gt;<span class="cm-braket">}</span> &lt;SWI number&gt;</span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 23px;"></div><div class="CodeMirror-gutters" style="display: none; height: 23px;"></div></div></div></pre></li></ul><h4><a name="psr访问指令" class="md-header-anchor"></a><span>PSR访问指令</span></h4><ul><li><span>使用MRS / MSR指令在 CPSR / SPSR寄存器与通用寄存器之间传输数据</span></li><li><span>MSR 指令允许全部或部分的寄存器内容被更新，通过写CPSR寄存器，可以开关中断、改变处理器模式</span></li><li><span>在用户模式下, 所有位都可读，但是仅有条件标志位（f）可以被改变</span></li></ul><p>&nbsp;</p><h4><a name="协处理器" class="md-header-anchor"></a><span>协处理器</span></h4><ul><li><p><span>ARM 体系支持16个协处理器，每个协处理器的指令集都占据了 ARM指令集的固定部分。如果系统中没有某个协处理器, 那么就会触发未定义指令异常</span></p></li><li><p><span>三种协处理器指令</span></p><ul><li><p><span>初始化协处理器数据操作指令：CDP</span></p></li><li><p><span>协处理器寄存器与ARM处理器寄存器数据传输指令</span></p><ul><li><span>MRC : 协处理器寄存器到ARM 处理器寄存器的数据传输指令</span></li><li><span>MCR : ARM 处理器寄存器到协处理器寄存器的数据传输指令</span></li></ul></li><li><p><span>协处理器寄存器和内存的数据传输指令 </span></p><ul><li><span>LDC : 协处理器数据加载指令</span></li><li><span>STC : 协处理器数据存储指令</span></li></ul></li></ul></li></ul><p>&nbsp;</p><h2><a name="arm编程模型四中断与异常" class="md-header-anchor"></a><span>ARM编程模型四：中断与异常</span></h2><ul><li><p><span>概述</span></p><ul><li><span>ARM处理器把外部中断、程序引起的软件中断以及CPU内部的异常事件都以异常模式来处理</span></li><li><span>ARM CPU将引起异常的原因分为7种，分别利用5种异常模式来对应，并使用中断向量表的方式进行异常响应</span></li><li><span>有些异常会同时发生，因而需要决定被响应的顺序。ARM对每个异常定义了优先级</span></li><li><span>为避免异常处理过程受到干扰，发生任何异常时，IRQ 中断被屏蔽。如果发生了FIQ或Reset异常，FIQ中断也会被屏蔽</span></li><li><span>ARM的异常返回在特权模式下进行，通常需要使用一条带“S”后缀，并以PC作为目标寄存器的数据传输指令。这不仅将PC的值更新，而且将SPSR寄存器的内容加载到了CPSR</span></li></ul></li><li><p><span>ARM各特定异常的具体处理</span></p><ul><li><p><span>系统上电和复位时，会进入复位异常。通常复位异常完成如下工作</span></p><ul><li><span>安装异常向量表</span></li><li><span>初始化存储系统 (例如： MMU/MPU)</span></li><li><span>初始化所有模式下的堆栈并设置寄存器</span></li><li><span>初始化 C 代码要求的变量</span></li><li><span>初始化所有连接的 I/O 设备</span></li><li><span>使能中断</span></li><li><span>改变处理器的模式和 / 或状态</span></li><li><span>调用main函数进入应用代码</span></li></ul></li><li><p><span>复位异常-》外部中断-》软件中断-》未定义指令-》中止异常-》复位异常</span></p></li></ul></li></ul><h2><a name="arm编程模型五外部io" class="md-header-anchor"></a><span>ARM编程模型五：外部IO</span></h2><ul><li><p><span>概述</span></p><ul><li><p><span>接口信息（所有信息均通过I/O端口来访问）</span></p><ul><li><p><span>数据信息</span></p><ul><li><span>可能为数字量（如键盘输入的信息以及显示器输出的信息等）、模拟量（如温度、压力、流量等）和开关量（如阀门的合与断、电路的开与关等）</span></li></ul></li><li><p><span>状态信息</span></p><ul><li><span>反映外设当前工作状态的信息，如READY信号（设备是否准备好）、BUSY信号(设备是否忙)等</span></li></ul></li><li><p><span>控制信息</span></p><ul><li><span>CPU向外部设备发送的控制命令信息。如读写控制信号、时序控制信号、中断信号、片选信号等</span></li></ul></li></ul></li></ul></li></ul><h2><a name="arm汇编程序格式" class="md-header-anchor"></a><span>ARM汇编程序格式</span></h2><ul><li><p><span>汇编语言(Assembly Language)是面向机器的程序设计语言</span></p></li><li><p><span>它用符号代替机器语言的二进制码，提高了程序的可读性和可维护性，同时也具有机器语言执行速度快，占内存空间少等优点</span></p></li><li><p><span>汇编语言的缺点是在编写复杂程序时具有明显的局限性，汇编语言依赖于具体的机型，不能通用，也不能在不同机型之间移植</span></p></li><li><p><span>在嵌入式系统中，汇编语言通常用于编写与微处理器架构和开发板相关的初始化程序、驱动程序、以及对于执行速度要求较高的程序</span></p></li><li><p><span>使用汇编语言编写的程序，机器不能直接识别，要由一种程序将汇编语言翻译成机器语言，这种起翻译作用的程序叫汇编程序（也叫汇编器）</span></p></li><li><p><span>ARM汇编程序设计的格式通常与具体使用的ARM汇编器相关。我们这里主要针对的是ARM公司提供的开发环境ARM Developer Suite及其兼容版本</span></p></li><li><p><span>键盘输入-》源程序-》计算机-》目标程序</span></p></li><li><p><span>汇编的hello world</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">AREA</span> &nbsp; <span class="cm-keyword">Buf</span>, DATA, READWRITE &nbsp; &nbsp; <span class="cm-comment">;声明数据段Buf</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Count</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">DCB</span> &nbsp; &nbsp; &nbsp; <span class="cm-keyword">20</span> &nbsp; &nbsp; &nbsp;  <span class="cm-tab" role="presentation" cm-text="	"> </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-comment">;定义一个字节单元Count</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">AREA</span> &nbsp; <span class="cm-keyword">Example</span>, CODE, READONLY &nbsp;<span class="cm-comment">;声明代码段Example</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">ENTRY</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-comment">;标识程序入口</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">CODE32</span> <span class="cm-tab" role="presentation" cm-text="	"> </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-comment">;声明32位ARM指令</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">START</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-keyword">LDRB</span> <span class="cm-variable">R0</span>, Count <span class="cm-tab" role="presentation" cm-text="	"> </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-comment">;R0 = Count =20</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" class="cm-tab-wrap-hack" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-keyword">MOV</span> <span class="cm-variable">R1</span>, <span class="cm-comment">#8 <span class="cm-tab" role="presentation" cm-text="	"> </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span>;R1 = 8</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-keyword">ADD</span> <span class="cm-variable">R0</span>, <span class="cm-variable">R0</span>, <span class="cm-variable">R1</span> <span class="cm-tab" role="presentation" cm-text="	"> </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-comment">;R0 = R0 + R1</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-keyword">B</span> <span class="cm-keyword">START</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">END</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 253px;"></div><div class="CodeMirror-gutters" style="display: none; height: 253px;"></div></div></div></pre></li></ul></li></ul><h3><a name="arm汇编程序的构成段" class="md-header-anchor"></a><span>ARM汇编程序的构成：段</span></h3><ul><li><span>ARM汇编语言的每个源程序由若干个段组成。每一个段是由若干个语句行组成。至少要有一个段</span></li><li><span>每一个段都有一个名字，并且段名是唯一的。每个段以符号AREA作为段的开始，以碰到下一个符号AREA作为该段的结束</span></li><li><span>段都有自己的属性，如是代码段（CODE）还是数据段（DATA），是只读（READONLY）还是可读写（READWRITE）</span></li><li><span>符号AREA和END都不能顶格写，只有标号可以而且必须顶格写</span></li></ul><h3><a name="arm汇编程序的构成---语句" class="md-header-anchor"></a><span>ARM汇编程序的构成—语句</span></h3><ul><li><p><span>语句就是完成一个动作的说明。可以分为以下两种类型</span></p><ul><li><span>指令性语句：汇编程序会把指令性语句翻译成机器代码，然后利用这些机器代码命令处理器执行某些操作。如由MOV、ADD等指令构造的语句。除了ARM指令集中规定的基本指令外，还包含一些由汇编器定义的宏指令</span></li><li><span>指示性语句：汇编程序并不把它们翻译成机器代码，只是用来指示、引导汇编程序在汇编时进行一些操作。如由ENTRY、AREA等指令构造的语句，我们也称这些指令为伪指令</span></li></ul></li><li><p><span>ARM（Thumb）汇编语言的语句格式为</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-braket">{</span>&lt;标号&gt;<span class="cm-braket">}</span>  &lt;指令或伪指令&gt; <span class="cm-braket">{</span><span class="cm-comment">;注释}</span></span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 23px;"></div><div class="CodeMirror-gutters" style="display: none; height: 23px;"></div></div></div></pre></li></ul></li><li><p><span>每一条指令的助记符可以全部用大写或全部用小写，但不允许在一条指令中大小写混用</span></p></li><li><p><span>如果一条语句太长，则可在行末用“\”来连接下一行</span></p></li><li><p><span>标号必须在顶格书写，其后面不要加“：”，对于变量的设置、常量的定义，其标识符必须顶格书写;而所有指令均不能顶格书写</span></p></li><li><p><span>注释使用“;”。注释内容由“;”开始到此行结束，注释可以在一行的顶格书写</span></p></li></ul><h3><a name="arm汇编程序格式---符号" class="md-header-anchor"></a><span>ARM汇编程序格式—符号</span></h3><ul><li><p><span>符号及符号定义伪指令</span></p><ul><li><p><span>这里所讲的符号特指用户在编写程序时自行定义的符号，不包含系统定义的指令助记符和保留字</span></p></li><li><p><span>符号的命名需注意以下规则</span></p><ul><li><span>由大小写字母、数字以及下划线组成</span></li><li><span>不能以数字开头（局部标号除外）</span></li><li><span>区分大小写，且所有字符都是有意义的</span></li><li><span>在其作用域范围内必须是唯一的</span></li><li><span>不能与系统内部或系统预定义的符号或指令助记符同名</span></li></ul></li><li><p><span>符号的用途分为三种：标号、常量和变量</span></p></li><li><p><span>标号：代表一个地址，段内标号的地址在汇编时确定，而段外标号的地址值在链接时确定</span></p></li><li><p><span>常量：在程序运行过程中，其值不能被改变的量</span></p><ul><li><span>按照数值类型可分为数字常量、字符串常量和逻辑常量</span></li></ul></li><li><p><span>变量：指存放在存储单元的操作数，并且它的值可以改变</span></p><ul><li><span>按照数值类型可分为数字变量、字符串变量和逻辑变量</span></li><li><span>按照变量的作用范围可以分为全局变量和局部变量</span></li></ul></li><li><p><span>逻辑真{TRUE}，逻辑假{FALSE}</span></p></li><li><figure><table><thead><tr><th><span>类型</span></th><th><span>伪指令</span></th><th><span>功能</span></th></tr></thead><tbody><tr><td><span>等效伪指令</span></td><td><span>EQU</span></td><td><span>为常量和标号定义一个等效的字符名称</span></td></tr><tr><td><span>全局变量定义伪指令</span></td><td><span>GBLA,GBLL,GBLS</span></td><td><span>定义一个全局数字变量，或逻辑变量，或字符串变量</span></td></tr><tr><td><span>局部变量定义伪指令</span></td><td><span>LCLA,LCLL,LCLS</span></td><td><span>定义一个局部数字变量，或逻辑变量，或字符串变量</span></td></tr><tr><td><span>变量赋值伪指令</span></td><td><span>SETA,SETL,SETS</span></td><td><span>为一个已经定义的全局或局部变量赋值</span></td></tr><tr><td><span>寄存器列表定义伪指令</span></td><td><span>RLIST</span></td><td><span>定义一个寄存器列表名称，针对LDM/STM指令</span></td></tr></tbody></table></figure><ul><li><p><span>等效伪指令EQU</span></p><ul><li><p><span>指令格式：name   EQU  </span><span>&lt;</span><span>expr&gt; {，type}</span></p></li><li><p><span>EQU伪指令用于为程序中的常量、标号等定义一个等效的字符名字，其作用类似于C语言中的#define</span></p></li><li><p><span>EQU也可用“*”代替</span></p></li><li><p><span>其表达式为32位常量时，可以指定表达式的数据类型，包括CODE16、CODE32和DATA</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Test</span> <span class="cm-keyword">EQU</span> <span class="cm-keyword">50</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-comment">;定义标号Test的值为50</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Addr</span> <span class="cm-keyword">EQU</span> <span class="cm-keyword">0x55</span>, CODE32 &nbsp; <span class="cm-comment">;定义Addr的值为0x55，且为32位的ARM指令</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 69px;"></div><div class="CodeMirror-gutters" style="display: none; height: 69px;"></div></div></div></pre></li></ul></li><li><p><span>定义全局变量伪指令</span></p><ul><li><p><span>指令格式：GBLA(GBLL,GBLS)  </span><span>&lt;</span><span>variable&gt;</span></p></li><li><p><span>GBLA、GBLL和GBLS伪指令用于定义一个ARM程序中的全局变量，并将其初始化</span></p></li><li><p><span>全局变量的变量名在整个程序范围内必须具有唯一性</span></p></li><li><p><span>GBLA 定义一个全局数字变量，其默认初值为0</span></p></li><li><p><span>GBLL 定义一个全局逻辑变量，其默认初值为假{FALSE}</span></p></li><li><p><span>GBLS 定义一个全局字符串变量，其默认初值为空</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">GBLA</span> <span class="cm-keyword">Test1</span> &nbsp; <span class="cm-comment">;定义一个全局数字变量，变量名为Test1</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">GBLL</span> <span class="cm-keyword">Test2</span> &nbsp; <span class="cm-comment">;定义一个全局逻辑变量，变量名为Test2</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">GBLS</span> <span class="cm-keyword">Test3</span> &nbsp; <span class="cm-comment">;定义一个全局字符串变量，变量名为Test3</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 69px;"></div><div class="CodeMirror-gutters" style="display: none; height: 69px;"></div></div></div></pre></li></ul></li><li><p><span>定义局部变量伪指令</span></p><ul><li><p><span>指令格式：LCLA(LCLL,LCLS)   </span><span>&lt;</span><span>variable&gt;</span></p></li><li><p><span>LCLA、LCLL和LCLS伪指令用于定义一个ARM程序中的局部变量，并将其初始化</span></p></li><li><p><span>局部变量的变量名在变量作用范围内必须具有唯一性。通常只在定义该变量的程序段内有效</span></p></li><li><p><span>LCLA 定义一个局部数字变量，其默认初值为0</span></p></li><li><p><span>LCLL 定义一个局部逻辑变量，其默认初值为假{FALSE}</span></p></li><li><p><span>LCLS 定义一个局部字符串变量，其默认初值为空</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">LCLA</span> <span class="cm-keyword">Test4</span> &nbsp; <span class="cm-comment">;定义一个局部数字变量，变量名为Test4</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">LCLL</span> <span class="cm-keyword">Test5</span> &nbsp; <span class="cm-comment">;定义一个局部逻辑变量，变量名为Test5</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">LCLS</span> <span class="cm-keyword">Test6</span> &nbsp; <span class="cm-comment">;定义一个局部字符串变量，变量名为Test6</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 69px;"></div><div class="CodeMirror-gutters" style="display: none; height: 69px;"></div></div></div></pre></li></ul></li><li><p><span>变量赋值伪指令</span></p><ul><li><p><span>指令格式：</span><span>&lt;</span><span>variable&gt;  SETA/SETL/SETS </span><span>&lt;</span><span>expr&gt;</span></p></li><li><p><span>伪指令SETA、SETL和SETS用于给一个已经定义的全局变量或局部变量进行赋值</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Test1</span> &nbsp;<span class="cm-keyword">SETA</span> &nbsp;<span class="cm-keyword">0xAA</span> &nbsp; &nbsp; &nbsp;  <span class="cm-tab" role="presentation" cm-text="	">   </span><span class="cm-comment">;将Test1变量赋值为0xAA</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Test2</span> &nbsp;<span class="cm-keyword">SETL</span> &nbsp;<span class="cm-braket">{</span>TRUE<span class="cm-braket">}</span><span class="cm-tab" role="presentation" cm-text="	"> </span> <span class="cm-tab" role="presentation" cm-text="	">   </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-comment">;将Test2变量赋值为真</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Test3</span> &nbsp;<span class="cm-keyword">SETS</span> “Testing”  <span class="cm-tab" role="presentation" cm-text="	"> </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-comment">;将Test3变量赋值为“Testing” </span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Test4</span> &nbsp;<span class="cm-keyword">SETA</span> &nbsp;<span class="cm-keyword">0xBB</span> &nbsp; &nbsp; &nbsp;  <span class="cm-tab" role="presentation" cm-text="	">   </span><span class="cm-comment">;将Test4变量赋值为0xBB</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Test5</span> &nbsp;<span class="cm-keyword">SETL</span> <span class="cm-braket">{</span>TRUE<span class="cm-braket">}</span>  <span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-comment">;将Test5变量赋值为真</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Test6</span> &nbsp;<span class="cm-keyword">SETS</span> “Testing”  <span class="cm-tab" role="presentation" cm-text="	"> </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-comment">;将Test6变量赋值为“Testing” </span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 138px;"></div><div class="CodeMirror-gutters" style="display: none; height: 138px;"></div></div></div></pre></li></ul></li><li><p><span>寄存器定义伪指令</span></p><ul><li><p><span>指令格式：</span><span>&lt;</span><span>name&gt;  RLIST &lt;{list}&gt;</span></p></li><li><p><span>指令LDM/STM需要使用一个比较长的寄存器列表，使用伪指令RLIST可对一个列表定义一个统一的名称</span></p></li><li><p><span>列表中的寄存器访问次序根据寄存器的编号由低到高，而与列表中的寄存器排列次序无关</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">RegListA</span> &nbsp;<span class="cm-keyword">RLIST</span> &nbsp;<span class="cm-braket">{</span><span class="cm-variable">R0</span>-<span class="cm-variable">R5</span>，<span class="cm-variable">R8</span>，<span class="cm-variable">R10</span><span class="cm-braket">}</span> &nbsp;<span class="cm-comment">;定义RegListA包含R0-R5,R8和R10。</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 69px;"></div><div class="CodeMirror-gutters" style="display: none; height: 69px;"></div></div></div></pre></li></ul></li></ul></li></ul></li><li><p><span>表达式和运算符</span></p><ul><li><p><span>表达式一般由变量、常量、运算符和括号构成</span></p></li><li><p><span>表达式有数字表达式、逻辑表达式和字符串表达式。另外还有一些特殊功能的表达式</span></p></li><li><p><span>运算次序遵循如下的优先级</span></p><ul><li><span>优先级相同的双目运算符的运算顺序为从左到右</span></li><li><span>相邻的单目运算符的运算顺序为从右到左，且单目运算符的优先级高于其他运算符</span></li><li><span>括号运算符的优先级最高</span></li></ul></li><li><p><span>数学表达式：</span></p><ul><li><p><span>算术运算：+-*/、MOD（%）</span></p></li><li><p><span>移位运算</span></p><ul><li><figure><table><thead><tr><th><span>运算符</span></th><th><span>表达式</span></th><th><span>意义</span></th></tr></thead><tbody><tr><td><span>ROL</span></td><td><span>X:ROL:Y</span></td><td><span>X循环左移Y位</span></td></tr><tr><td><span>ROR</span></td><td><span>X :ROR: Y</span></td><td><span>X循环右移Y位</span></td></tr><tr><td><span>SHL</span></td><td><span>X :SHL: Y</span></td><td><span>X左移Y位</span></td></tr><tr><td><span>SHR</span></td><td><span>X:SHR:Y</span></td><td><span>X右移Y位</span></td></tr></tbody></table></figure></li></ul></li><li><p><span>按位逻辑运算</span></p><ul><li><figure><table><thead><tr><th><span>运算符</span></th><th><span>表达式</span></th><th><span>意义</span></th></tr></thead><tbody><tr><td><span>AND</span></td><td><span>X:AND:Y</span></td><td><span>X与Y按位逻辑与</span></td></tr><tr><td><span>OR</span></td><td><span>X :OR: Y</span></td><td><span>X与Y按位逻辑或</span></td></tr><tr><td><span>NOT</span></td><td><span>:NOT: Y</span></td><td><span>Y按位逻辑非</span></td></tr><tr><td><span>EOR</span></td><td><span>X:EOR:Y</span></td><td><span>X与Y按位逻辑异或</span></td></tr></tbody></table></figure></li></ul></li><li><p><span>算术关系运算符</span></p><ul><li><figure><table><thead><tr><th><span>运算符</span></th><th><span>表达式</span></th><th><span>意义</span></th></tr></thead><tbody><tr><td><span>=</span></td><td><span>X = Y</span></td><td><span>X等于Y</span></td></tr><tr><td><span>&gt;</span></td><td><span>X &gt; Y</span></td><td><span>X大于Y</span></td></tr><tr><td><span>&lt;</span></td><td><span>X &lt; Y</span></td><td><span>X小于Y</span></td></tr><tr><td><span>&gt;=</span></td><td><span>X &gt;= Y</span></td><td><span>X大于等于Y</span></td></tr><tr><td><span>&lt;=</span></td><td><span>X &lt;= Y</span></td><td><span>X小于等于Y</span></td></tr><tr><td><span>/=,&lt;&gt;</span></td><td><span>X/=Y</span><br><span>X&lt;&gt;=Y</span></td><td><span>X不等于Y</span></td></tr></tbody></table></figure></li></ul></li><li><p><span>逻辑关系运算</span></p><ul><li><figure><table><thead><tr><th><span>运算符</span></th><th><span>表达式</span></th><th><span>意义</span></th></tr></thead><tbody><tr><td><span>LAND</span></td><td><span>X:LAND:Y</span></td><td><span>X与Y逻辑与</span></td></tr><tr><td><span>LOR</span></td><td><span>X :LOR: Y</span></td><td><span>X与Y逻辑或</span></td></tr><tr><td><span>LNOT</span></td><td><span>:LNOT: Y</span></td><td><span>Y逻辑非</span></td></tr><tr><td><span>LEOR</span></td><td><span>X:LEOR:Y</span></td><td><span>X与Y逻辑异或</span></td></tr></tbody></table></figure></li></ul></li><li><p><span>字符串表达式</span></p><ul><li><figure><table><thead><tr><th><span>运算符</span></th><th><span>表达式</span></th><th><span>意义</span></th></tr></thead><tbody><tr><td><span>LEN</span></td><td><span>:LEN:X</span></td><td><span>字符串X的长度</span></td></tr><tr><td><span>CHR</span></td><td><span>:CHR:M</span></td><td><span>将整数M(0-255)转换为一个字符</span></td></tr><tr><td><span>STR</span></td><td><span>:STR:X</span></td><td><span>将数字或逻辑表达式X转换为一个字符串</span></td></tr><tr><td><span>LEFT</span></td><td><span>X:LEFT:Y</span></td><td><span>返回字符串X最左边的Y个字符</span></td></tr><tr><td><span>RIGHT</span></td><td><span>X:RIGHT:Y</span></td><td><span>返回字符串X最右边的Y个字符</span></td></tr><tr><td><span>CC</span></td><td><span>X:CC:Y</span></td><td><span>将字符串X和Y连接起来，Y在X后边</span></td></tr></tbody></table></figure></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">; 假设已定义Str1，Str2，Str3三个字符串变量</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Str1</span> &nbsp;<span class="cm-keyword">SETS</span> &nbsp; “AAACCC” &nbsp;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Str2</span> &nbsp;<span class="cm-keyword">SETS</span> :<span class="cm-tag">STR:</span> (:<span class="cm-tag">LEN:</span>Str1) &nbsp; <span class="cm-tab" role="presentation" cm-text="	"> </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-comment">;Str2 = “00000006”</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Str3</span> &nbsp;<span class="cm-keyword">SETS</span>  “BBB”:<span class="cm-tag">CC:</span> (<span class="cm-tag">Str1:LEFT:</span>3) <span class="cm-comment">;Str3=“BBBAAA”</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 92px;"></div><div class="CodeMirror-gutters" style="display: none; height: 92px;"></div></div></div></pre></li></ul></li><li><p><span>其他表达式</span></p><ul><li><figure><table><thead><tr><th><span>运算符</span></th><th><span>表达式</span></th><th><span>意义</span></th></tr></thead><tbody><tr><td><span>BASE</span></td><td><span>:BASE:X</span></td><td><span>返回基于寄存器的表达式X中的寄存器编号</span></td></tr><tr><td><span>INDEX</span></td><td><span>:INDEX:X</span></td><td><span>返回基于寄存器的表达式X中的偏移量</span></td></tr><tr><td><span>？</span></td><td><span>?X</span></td><td><span>返回符号X的代码行所生成的可执行代码字节数</span></td></tr><tr><td><span>DEF</span></td><td><span>:DEF:X</span></td><td><span>判断符号X是否已经定义</span></td></tr></tbody></table></figure></li></ul></li></ul></li></ul></li><li><p><span>表达式中的变量代换</span></p><ul><li><p><span>程序中的变量可通过代换操作取得一个常量。代换操作符为“$”</span></p></li><li><p><span>数字变量：将该数字变量的值转换为十六进制的字符串，并将该十六进制的字符串代换“$” 后的数字变量</span></p></li><li><p><span>逻辑变量：将该逻辑变量代换为它的取值（真或假）</span></p></li><li><p><span>字符串变量：将该字符串变量的值代换 “$” 后的字符串变量</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">LCLS</span> &nbsp;<span class="cm-keyword">s1</span> <span class="cm-comment">;定义局部字符串变量S1和S2</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">LCLS</span> &nbsp;<span class="cm-keyword">s2</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">s1</span> <span class="cm-keyword">SETS</span> “Test !”</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">s2</span> <span class="cm-keyword">SETS</span> “This is a $s1” <span class="cm-comment">; 字符串变量S2的值为“This is a Test !”</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 92px;"></div><div class="CodeMirror-gutters" style="display: none; height: 92px;"></div></div></div></pre></li></ul></li></ul><h3><a name="段定义伪指令" class="md-header-anchor"></a><span>段定义伪指令</span></h3><ul><li><p><span>指令格式：AREA </span><span>&lt;</span><span>sectionname&gt;  {</span><span>&lt;</span><span>attr&gt;}{,</span><span>&lt;</span><span>attr&gt;}…</span></p></li><li><p><span>sectionname：段名，若段名以数字开头，则必须用符号“|”扩起来，如|1_test|。</span></p></li><li><p><span>attr：属性字段，多个属性字段用逗号分隔。</span></p></li><li><figure><table><thead><tr><th><span>属性</span></th><th><span>含义</span></th><th><span>备注</span></th></tr></thead><tbody><tr><td><span>CODE</span></td><td><span>代码段</span></td><td><span>默认读/写属性为READONLY</span></td></tr><tr><td><span>DATA</span></td><td><span>数据段</span></td><td><span>默认读/写属性为READWRITE</span></td></tr><tr><td><span>READONLY</span></td><td><span>本段为只读</span></td><td>&nbsp;</td></tr><tr><td><span>READWRITE</span></td><td><span>本段为可读可写</span></td><td>&nbsp;</td></tr><tr><td><span>ALIGN表达式</span></td><td><span>对齐字节数</span></td><td><span>ELF的代码段和数据段为字对齐</span></td></tr><tr><td><span>COMMON</span></td><td><span>多源文件共享段</span></td><td>&nbsp;</td></tr></tbody></table></figure></li></ul><p>&nbsp;</p><h3><a name="数据定义伪指令" class="md-header-anchor"></a><span>数据定义伪指令</span></h3><ul><li><figure><table><thead><tr><th><span>类型</span></th><th><span>伪指令</span></th><th><span>功能</span></th></tr></thead><tbody><tr><td><span>数据空间分配</span></td><td><span>DCB(=)/DCW(DCWU)/DCD(&amp;，DCDU)/DCQ(DCQU)</span></td><td><span>分配连续的字节/半字/字/双字存储单元并初始化</span></td></tr><tr><td>&nbsp;</td><td><span>DCFD(DCFDU)/DCFS(DCFSU)</span></td><td><span>分配连续的双精度/单精度浮点数存储单元并初始化</span></td></tr><tr><td>&nbsp;</td><td><span>SPACE(%)</span></td><td><span>分配指定大小的连续存储单元并初始化为0</span></td></tr><tr><td><span>文字池定义</span></td><td><span>LTORG</span></td><td><span>定义一个暂存数据的数据缓冲区，即文字池</span></td></tr><tr><td><span>数据表定义</span></td><td><span>MAP, FIELD</span></td><td><span>定义一个结构化的内存表首地址和数据域</span></td></tr></tbody></table></figure></li><li><p><span>DCB</span></p><ul><li><p><span>指令格式：{label} DCB expr{，expr}{，expr}…</span></p><ul><li><span>label标号：代表存储区首地址（可选）</span></li><li><span>DCB可用“=”代替</span></li><li><span>expr表达式：数字（0-255）或字符串（可有多个，逗号分隔）</span></li></ul></li><li><p><span>DCB伪指令用于分配一片连续的以字节为单位的存储区域，并用指定的表达式对其进行初始化</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Dat1</span> &nbsp;<span class="cm-keyword">DCB</span> &nbsp; <span class="cm-keyword">0x7E</span>,0x19 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-comment">;分配两个字节的空间，并初始化成0x7E和0x19</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Str</span> &nbsp; &nbsp; &nbsp;<span class="cm-keyword">DCB</span> &nbsp; “ This is a test ! ” &nbsp; <span class="cm-comment">;分配连续字节单元并初始化成指定字符串</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 92px;"></div><div class="CodeMirror-gutters" style="display: none; height: 92px;"></div></div></div></pre></li></ul></li><li><p><span>DCW,DCD,DCQ</span></p><ul><li><p><span>指令格式：{label} DCW/DCD/DCQ expr{，expr}{，expr}…</span></p></li><li><p><span>DCD可用“=”代替</span></p></li><li><p><span>expr表达式：标号或数字表达式（可有多个，逗号分隔）</span></p></li><li><p><span>DCW/DCD/DCQ伪指令用于分配一片连续的以半字/字/双字为单位的存储区域，并用指定的表达式对其进行初始化</span></p></li><li><p><span>DCW/DCD/DCQ分配的存储单元是严格按半字/字/双字对齐的，如希望不必严格对齐，可使用DCWU/DCDU/DCQU伪指令</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">DataTest</span> <span class="cm-keyword">DCW</span> <span class="cm-keyword">1</span>,2,3 &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-comment">;分配连续三个2字节对齐的存储区</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">DataTest</span> &nbsp;<span class="cm-keyword">DCD</span> <span class="cm-keyword">4</span>,5,6 &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-comment">;分配连续三个4字节对齐的存储区</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">DataTest</span> <span class="cm-keyword">DCQ</span> <span class="cm-keyword">100</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-comment">;分配连续一个8字节对齐的存储区</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 69px;"></div><div class="CodeMirror-gutters" style="display: none; height: 69px;"></div></div></div></pre></li></ul></li><li><p><span>DCFD,DCFS</span></p><ul><li><p><span>指令格式：{label} DCFD/DCFS expr{，expr}{，expr}…</span></p></li><li><p><span>DCFD/DCFS伪指令用于为双精度/单精度的浮点数分配一片连续的字存储单元，并用伪指令中指定的表达式初始化。每个双精度的浮点数占据两个字单元（8字节），每个单精度浮点数占据一个字单元（4字节）</span></p></li><li><p><span>DCFD/DCFS分配的存储单元是严格按8字节/4字节对齐的，如希望不必严格对齐，可使用FCFDU/DCFSU伪指令</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">FDataTest</span> <span class="cm-keyword">DCFD</span> <span class="cm-keyword">2E115</span>,-5E7 &nbsp; <span class="cm-comment">;分配连续两个8字节对齐的存储区并初始化</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">FDataTest</span> <span class="cm-keyword">DCFS</span> &nbsp;<span class="cm-keyword">2E5</span>,-5E-7 &nbsp; &nbsp; &nbsp; <span class="cm-comment">;分配连续两个4字节对齐的存储区并初始化</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 69px;"></div><div class="CodeMirror-gutters" style="display: none; height: 69px;"></div></div></div></pre></li></ul></li><li><p><span>SPACE</span></p><ul><li><p><span>指令格式：{label}    SPACE    expr</span></p></li><li><p><span>SPACE伪指令用于分配一片连续的存储区域并初始化为0</span></p></li><li><p><span>表达式为要分配的字节数，SPACE也可用“%”代替</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">DataSpace</span> <span class="cm-keyword">SPACE</span> <span class="cm-keyword">100</span> &nbsp; &nbsp; &nbsp; <span class="cm-comment">;分配连续的100字节的存储单元并初始化为0</span></span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 23px;"></div><div class="CodeMirror-gutters" style="display: none; height: 23px;"></div></div></div></pre></li></ul></li><li><p><span>LTORG</span></p><ul><li><p><span>指令格式：LTORG</span></p></li><li><p><span>伪指令 LTORG 用来说明某个存储区域为一个用来暂存数据的数据缓冲区，也叫文字池或数据缓冲池。大的代码段也可以使用多个数据缓冲池</span></p></li><li><p><span>当程序中使用 LDR 之类的指令访问数据缓冲池时，为防止越界发生，通常把数据缓冲池放在代码段的最后面，或放在无条件转移指令或子程序返回指令之后，这样处理器就不会错误地将数据缓冲池中的数据当作指令来执行</span></p></li><li><p><span>如果没有使用LTORG声明文字池，则汇编器会在程序末尾自动声明</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">AREA</span> <span class="cm-keyword">example</span>, CODE, READONLY</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Start</span> &nbsp; &nbsp;<span class="cm-keyword">BL</span> &nbsp;<span class="cm-keyword">Func1</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  …</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Func1</span> &nbsp;<span class="cm-keyword">LDR</span> <span class="cm-variable">R1</span>,<span class="cm-tag">=0x800</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-keyword">MOV</span> <span class="cm-variable-2">PC</span>,<span class="cm-variable-2">LR</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-keyword">LTORG</span> &nbsp;<span class="cm-comment">; </span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Date</span> &nbsp; &nbsp;<span class="cm-keyword">SPACE</span> &nbsp;<span class="cm-keyword">40</span> <span class="cm-comment">;</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; <span class="cm-keyword">END</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 184px;"></div><div class="CodeMirror-gutters" style="display: none; height: 184px;"></div></div></div></pre></li></ul></li><li><p><span>MAP和FIELD</span></p><ul><li><p><span>指令格式：MAP </span><span>&lt;</span><span>expr1&gt; {,</span><span>&lt;</span><span>baseregister&gt;}        /      </span><span>&lt;</span><span>label&gt;   FIELD  </span><span>&lt;</span><span>expr2&gt;</span></p><ul><li><span>expr1标号或数字表达式</span></li><li><span>baseregister基址寄存器，与expr之和就是结构化数据表的首地址</span></li><li><span>label标号</span></li><li><span>expr2数据域所占字节数</span></li></ul></li><li><p><span>MAP用于定义一个结构化的内存表的首地址。FIELD伪指令用于定义一个结构化内存表中的数据域。两者配合起来实现一个类似C语言中结构的功能</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">MAP</span> &nbsp; &nbsp;<span class="cm-keyword">0x100</span> &nbsp;  <span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-comment">;定义结构化内存表首地址为0x100</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">A</span> &nbsp; &nbsp; &nbsp; <span class="cm-keyword">FIELD</span> &nbsp; <span class="cm-keyword">16</span> <span class="cm-tab" role="presentation" cm-text="	"> </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-comment">;定义A的长度为16字节，位置为0x100</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">B</span> &nbsp; &nbsp; &nbsp; <span class="cm-keyword">FIELD</span> &nbsp; <span class="cm-keyword">32</span> <span class="cm-tab" role="presentation" cm-text="	"> </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-comment">;定义B的长度为32字节，位置为0x110</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">S</span> &nbsp; &nbsp; &nbsp; <span class="cm-keyword">FIELD</span> &nbsp; &nbsp;<span class="cm-keyword">256</span> <span class="cm-tab" role="presentation" cm-text="	">   </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-comment">;定义S的长度为256字节，位置为0x130</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 92px;"></div><div class="CodeMirror-gutters" style="display: none; height: 92px;"></div></div></div></pre></li><li><p><span>ARM汇编程序格式—汇编控制伪指令</span></p><ul><li><figure><table><thead><tr><th><span>类型</span></th><th><span>伪指令</span></th><th><span>功能</span></th></tr></thead><tbody><tr><td><span>条件汇编</span></td><td><span>IF,ELSE,ENDIF</span></td><td><span>根据条件是否成立来决定汇编某个程序段</span></td></tr><tr><td><span>重复汇编</span></td><td><span>WHILE, WEND</span></td><td><span>根据条件是否成立来决定是否重复汇编一个程序段</span></td></tr><tr><td><span>宏定义</span></td><td><span>MACRO,MEND,MEXIT</span></td><td><span>定义一个可以带参数的程序段，可使用宏名来引用</span></td></tr></tbody></table></figure></li></ul></li><li><p><span>条件汇编：IF,ELSE,ENDIF</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly" style="break-inside: unset;"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">;指令格式： &nbsp; IF 逻辑表达式</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 程序段1</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 程序段2</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  ENDIF</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">GBLL</span> <span class="cm-keyword">CONFIG</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">IF</span> &nbsp;<span class="cm-keyword">CONFIG</span> <span class="cm-tag">=</span> TRUE</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; <span class="cm-keyword">BNE</span> <span class="cm-builtin">__rt_udiv_1</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; <span class="cm-keyword">LDR</span> <span class="cm-variable">R0</span>, <span class="cm-tag">=__rt_div0</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; <span class="cm-variable">BX</span> <span class="cm-variable">R0</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">ELSE</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; <span class="cm-keyword">BEQ</span> <span class="cm-builtin">__rt_div0</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">ENDIF</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 345px;"></div><div class="CodeMirror-gutters" style="display: none; height: 345px;"></div></div></div></pre></li><li><p><span>根据条件的成立与否决定是否执行某个程序段</span></p></li><li><p><span>可以嵌套使用</span></p></li><li><p><span>有时为了简单起见，IF,ELSE,ENDIF可以分别用[,|,]代替</span></p></li></ul></li><li><p><span>重复汇编：WHILE,WEND</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">;指令格式： &nbsp; WHILE 逻辑表达式</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 程序段</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WEND</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; <span class="cm-keyword">GBLA</span> <span class="cm-keyword">no</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">no</span> <span class="cm-keyword">SETA</span> &nbsp;<span class="cm-keyword">3</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">WHILE</span> <span class="cm-keyword">no</span>&lt;5</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; <span class="cm-keyword">no</span> <span class="cm-keyword">SETA</span> <span class="cm-keyword">no</span>+1</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; ...</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">WEND</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 207px;"></div><div class="CodeMirror-gutters" style="display: none; height: 207px;"></div></div></div></pre></li><li><p><span>根据条件的成立与否决定是否重复汇编一个程序段</span></p></li><li><p><span>若WHILE后面的逻辑表达式为真，则重复汇编该程序段，直到逻辑表达式为假</span></p></li><li><p><span>可以嵌套使用</span></p></li></ul></li><li><p><span>宏定义：MACRO,MEND,MEXIT</span></p><ul><li><p><span>这里的宏和C语言中的概念类似。在源程序被编译时，汇编器将宏调用展开，用宏定义中的指令序列替换程序中宏名的调用，并将实际参数的值传递给宏定义中的参数</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">;指令格式： &nbsp; MACRO</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $标号 &nbsp; 宏名 $参数1， $参数2，…..宏名称，为宏在程序中的调用名,主标号，宏内的所有其它标号必须由主标号组成</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 程序段（宏定义体，可包含MEXIT）</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MEND</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 115px;"></div><div class="CodeMirror-gutters" style="display: none; height: 115px;"></div></div></div></pre></li><li><p><span>MACRO定义一个宏语句段的开始，MEND定义宏语句段的结束，MEXIT可以实现从宏程序段的跳出。使用方法是通过宏指令的方式来调用</span></p></li><li><p><span>宏指令的参数必须前面加$符号，类似于函数的形参，可以有0-n个</span></p></li></ul></li><li><p><span>宏定义：MACRO,MEND,MEXIT</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">MACRO</span> <span class="cm-keyword">DTX</span> $date, $time</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp;<span class="cm-keyword">LDR</span> <span class="cm-variable">R1</span>, <span class="cm-tag">=</span> 0x1000 &nbsp;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp;<span class="cm-keyword">LDR</span> <span class="cm-variable">R0</span>, <span class="cm-tag">=</span> $date </span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp;<span class="cm-keyword">STR</span> <span class="cm-variable">R0</span>, [<span class="cm-variable">R1</span>], <span class="cm-comment">#04</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp;<span class="cm-keyword">LDR</span> <span class="cm-variable">R2</span>, <span class="cm-tag">=</span> $time</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp;<span class="cm-keyword">STR</span> <span class="cm-variable">R2</span>, [<span class="cm-variable">R1</span>]</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">MEND</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 161px;"></div><div class="CodeMirror-gutters" style="display: none; height: 161px;"></div></div></div></pre></li></ul></li><li><p><span>宏指令—ADR,ADRL</span></p><ul><li><p><span>在ARM中，还有一种汇编器内置的宏指令。在汇编时，这些宏指令被替换成一条或两条真正的ARM或Thumb指令</span></p></li><li><p><span>近地址读取指令:   ADR{cond}  </span><span>&lt;</span><span>reg&gt;, </span><span>&lt;</span><span>expr&gt;</span></p><ul><li><span>用于将一个近地址值传递到一个寄存器中</span></li><li><span>在汇编时将被替换成一条真正的ADD或SUB指令，以当前的PC值为基准，加上或减去一个偏移量</span></li><li><span>标号地址不能距离当前PC过远（非字对齐255字节以内;字对齐1020字节以内）</span></li></ul></li><li><p><span>远地址读取指令： ADRL{cond}  </span><span>&lt;</span><span>reg&gt;, </span><span>&lt;</span><span>expr&gt;</span></p><ul><li><span>与ADR类似，但会替换成两条ADD或SUB指令。因而可以表达更远的地址</span></li><li><span>找不到合适的指令时则会报错</span></li></ul></li></ul></li><li><p><span>宏指令—ADR,ADRL</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">start</span> &nbsp;<span class="cm-keyword">MOV</span> <span class="cm-variable">R0</span>,<span class="cm-comment">#10</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-keyword">ADR</span> <span class="cm-variable">R4</span>, start</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">start</span> &nbsp;<span class="cm-keyword">MOV</span> <span class="cm-variable">R0</span>,<span class="cm-comment">#10</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-keyword">ADRL</span> <span class="cm-variable">R4</span>,start+60000</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 92px;"></div><div class="CodeMirror-gutters" style="display: none; height: 92px;"></div></div></div></pre></li></ul></li><li><p><span>宏指令—LDR,NOP</span></p><ul><li><p><span>全范围地址读取指令LDR   LDR{cond} reg,={expr | label - expr}</span></p><ul><li><span>用于将任意一个32位地址值传递到一个寄存器中</span></li><li><span>汇编器在汇编时，若expr的值允许，则产生一条MOV或MVN指令，否则用文字池的方式来产生一条LDR指令和一个DCD数据定义</span></li><li><span>在前面的ARM指令集中已经介绍过</span></li></ul></li><li><p><span>空指令NOP</span></p><ul><li><span>汇编时替换成MOV R0,R0</span></li></ul></li></ul></li><li><p><span>ARM汇编程序格式—其它伪指令</span></p><ul><li><figure><table><thead><tr><th><span>伪指令</span></th><th><span>功能</span></th></tr></thead><tbody><tr><td><span>ALIGH</span></td><td><span>填充字节使当前位置满足对齐要求</span></td></tr><tr><td><span>CODE16,CODE32</span></td><td><span>指定采用的指令集</span></td></tr><tr><td><span>ENTRY</span></td><td><span>指定汇编程序的入口点</span></td></tr><tr><td><span>END</span></td><td><span>通知汇编器结束汇编</span></td></tr><tr><td><span>EXPORT,GLOBAL</span></td><td><span>声明一个能被其它源文件引用的符号</span></td></tr><tr><td><span>IMPORT,EXTERN</span></td><td><span>声明要引用一个外部符号</span></td></tr><tr><td><span>GET,INCLUDE</span></td><td><span>包含一个源文件</span></td></tr><tr><td><span>INCBIN</span></td><td><span>包含一个目标文件或数据文件</span></td></tr><tr><td><span>RN</span></td><td><span>定义寄存器别名</span></td></tr><tr><td><span>ROUT</span></td><td><span>定义局部变量作用范围</span></td></tr></tbody></table></figure></li></ul></li><li><p><span>定义对齐方式伪指令ALIGN</span></p><ul><li><p><span>指令格式：ALIGN  {expr {，偏移量}}</span></p></li><li><p><span>使用ALIGN伪指令可用添加填充字节的方式，使当前位置实现某种对齐方式</span></p></li><li><p><span>对齐方式为2表达式的值。偏移量为一个数字表达式，若使用该字段，则当前位置的对齐方式为2表达式的值 + 偏移量</span></p></li><li><p><span>若定义段的对齐，则使用ALIGN=expr格式</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">AREA</span> <span class="cm-keyword">Init</span>, CODE, READONLY, ALIGN<span class="cm-tag">=3</span> <span class="cm-comment">;;指定8字节对齐代码段</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-keyword">END</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 46px;"></div><div class="CodeMirror-gutters" style="display: none; height: 46px;"></div></div></div></pre></li></ul></li><li><p><span>CODE16,CODE32</span></p><ul><li><p><span>指令格式：CODE16 /CODE32</span></p></li><li><p><span>CODE16用来表明其后的指令均为16位Thumb指令</span></p></li><li><p><span>CODE32伪指令则表明其后面的指令均为32位ARM指令</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">AREA</span> <span class="cm-keyword">Init</span>, CODE, READONLY</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">…..</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">CODE32</span> </span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">LDR</span> <span class="cm-variable">R0</span>,<span class="cm-tag">=NEXT</span> + 1 </span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">BX</span> <span class="cm-variable">R0</span> <span class="cm-comment">;将处理器切换到Thumb工作状态</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">CODE16</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">NEXT</span> <span class="cm-keyword">LDR</span> <span class="cm-variable">R3</span>,<span class="cm-tag">=0X3FF</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">…</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">END</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 207px;"></div><div class="CodeMirror-gutters" style="display: none; height: 207px;"></div></div></div></pre></li></ul></li><li><p><span>ENTRY,END</span></p><ul><li><p><span>指令格式：ENTRY/END</span></p></li><li><p><span>ENTRY伪指令用于指定汇编程序的入口点</span></p></li><li><p><span>END伪指令用于通知编译器汇编工作到此结束，不再往下汇编了</span></p></li><li><p><span>一个ARM工程里面，只能有一个ENTRY，但每个源文件都必须有END</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">AREA</span> <span class="cm-keyword">Init</span>, CODE, READONLY</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ENTRY<span class="cm-comment">;</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  …..</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">END</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 92px;"></div><div class="CodeMirror-gutters" style="display: none; height: 92px;"></div></div></div></pre></li></ul></li><li><p><span>EXPORT,GLOBAL</span></p><ul><li><p><span>指令格式： EXPORT/GLOBAL  符号   {[WEAK]}</span></p></li><li><p><span>用伪指令EXPORT或GLOBAL可以声明一个其他源文件可引用的符号，这种符号也叫做外部可引用符号</span></p></li><li><p><span>[WEAK]选项声明其他的同名符号优先于该符号被引用</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">AREA</span> &nbsp;<span class="cm-keyword">Init</span>, CODE, READONLY</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;<span class="cm-keyword">EXPORT</span> <span class="cm-keyword">Stest</span> <span class="cm-comment">; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 表示Stest可被其它源文件引用</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">  …</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;<span class="cm-keyword">END</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 92px;"></div><div class="CodeMirror-gutters" style="display: none; height: 92px;"></div></div></div></pre></li></ul></li><li><p><span>IMPORT、EXTERN</span></p><ul><li><p><span>指令格式：IMPORT/EXTERN  符号  {[WEAK]}</span></p></li><li><p><span>当在一个源文件中需要使用另外一个源文件的外部可引用符号时，必须使用伪指令 IMPORT或EXTERN对其进行声明</span></p></li><li><p><span>[WEAK]选项表示当前所有的源文件都没有定义这样一个符号时，编译器也不报错，一般将该符号置为0。但当该符号被B或BL指令所引用时，则将B或BL指令置为NOP操作</span></p></li><li><p><span>如果源文件声明了一个引用符号但未真正使用，用IMPORT该符号会被加入到当前源文件的符号表中，而用EXTERN则不会</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">IMPORT</span> &nbsp;<span class="cm-keyword">Main</span> &nbsp; &nbsp;<span class="cm-comment">;表示需要引用Main符号</span></span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 23px;"></div><div class="CodeMirror-gutters" style="display: none; height: 23px;"></div></div></div></pre></li></ul></li><li><p><span>GET/INCLUDE,INCBIN</span></p><ul><li><p><span>指令格式： GET/INCLUDE/INCBIN  文件名\</span></p></li><li><p><span>GET或INCLUDE伪指令用于将一个源文件包含到当前的源文件中，并将被包含的源文件在当前位置进行汇编</span></p></li><li><p><span>INCBIN伪指令用于将一个目标文件或数据文件包含到当前的源文件中，被包含的文件不做任何变动地存放在当前文件中，编译器从其后开始继续处理</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">AERA</span> <span class="cm-keyword">Init</span>, CODE, READONLY</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; <span class="cm-keyword">GET</span> <span class="cm-keyword">a1</span>.s</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; <span class="cm-keyword">GET</span> <span class="cm-tag">c:</span>\a2.s</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; <span class="cm-keyword">INCBIN</span> <span class="cm-keyword">a1</span>.dat</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; <span class="cm-keyword">INCBIN</span> <span class="cm-tag">c:</span>\a2.txt</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; … </span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; <span class="cm-keyword">END</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 161px;"></div><div class="CodeMirror-gutters" style="display: none; height: 161px;"></div></div></div></pre></li></ul></li><li><p><span>RN</span></p><ul><li><p><span>指令格式：</span><span>&lt;</span><span>name&gt;  RN </span><span>&lt;</span><span>expr&gt;</span></p></li><li><p><span>RN伪指令用于给一个寄存器定义一个别名，以提高程序的可读性</span></p></li><li><p><span>expr：寄存器名</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Temp</span> &nbsp;<span class="cm-keyword">RN</span> &nbsp;<span class="cm-variable">R0</span> &nbsp; &nbsp; &nbsp;<span class="cm-comment">;将R0定义一个别名Temp</span></span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 23px;"></div><div class="CodeMirror-gutters" style="display: none; height: 23px;"></div></div></div></pre></li></ul></li><li><p><span>ROUT</span></p><ul><li><span>指令格式：</span><span>&lt;</span><span>name&gt;  ROUT</span></li><li><span>ROUT伪指令用于给一个局部变量定义作用范围</span></li><li><span>程序中未使用该伪指令时，局部变量的作用范围为所在的AREA;而使用ROUT后，局部变量的作用范围为当前ROUT和下一个ROUT之间</span></li></ul></li></ul></li></ul><h2><a name="arm汇编程序设计" class="md-header-anchor"></a><span>ARM汇编程序设计</span></h2><ul><li><p><span>段和顺序程序设计</span></p><ul><li><span>在ARM（Thumb）汇编语言程序中，通常以段为单位来组织代码。段是具有特定名称且功能相对独立的指令或数据序列。根据段的内容，分为代码段和数据段</span></li><li><span>一个汇编程序至少应该有一个代码段，当程序较长时，可以分割为多个代码段和数据段</span></li><li><span>最简单的程序是没有分支、没有循环的顺序运行程序</span></li></ul></li><li><p><span>顺序程序设计示例</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly" style="break-inside: unset;"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">AREA</span> <span class="cm-keyword">Buf</span>, DATA, READWRITE <span class="cm-comment">;定义数据段Buf</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Array</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">DCD</span> <span class="cm-keyword">0x11</span>, 0x22, 0x33, 0x44 <span class="cm-comment">;定义数组Array</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">DCD</span> <span class="cm-keyword">0x55</span>, 0x66, 0x77, 0x88</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">DCD</span> <span class="cm-keyword">0x00</span>, 0x00, 0x00, 0x00</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">AREA</span> <span class="cm-keyword">Example</span>, CODE, READONLY</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">ENTRY</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">CODE32</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">LDR</span> &nbsp; &nbsp; &nbsp; <span class="cm-variable">R0</span>, <span class="cm-tag">=</span> Array <span class="cm-comment">;取得数组Array首地址</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">LDR</span> &nbsp; &nbsp; &nbsp; <span class="cm-variable">R2</span>, [<span class="cm-variable">R0</span>] <span class="cm-comment">;数组第1项→ R2</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">MOV</span> &nbsp; &nbsp; <span class="cm-variable">R1</span>, <span class="cm-comment">#4</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">LDR</span> &nbsp; &nbsp; &nbsp; <span class="cm-variable">R3</span>, [<span class="cm-variable">R0</span>, <span class="cm-variable">R1</span>, LSL <span class="cm-comment">#2] ;数组第5项→ R3</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">ADD</span> &nbsp; &nbsp; &nbsp;<span class="cm-variable">R2</span>, <span class="cm-variable">R2</span>, <span class="cm-variable">R3</span> <span class="cm-comment">;R2 + R3 → R2</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">MOV</span> &nbsp; &nbsp; <span class="cm-variable">R1</span>, <span class="cm-comment">#8 ;R1 = 8</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">STR</span> &nbsp; &nbsp; &nbsp; <span class="cm-variable">R2</span>, [<span class="cm-variable">R0</span>, <span class="cm-variable">R1</span>, LSL <span class="cm-comment">#2] ;保存结果到数组第9项</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-keyword">END</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 391px;"></div><div class="CodeMirror-gutters" style="display: none; height: 391px;"></div></div></div></pre></li></ul></li><li><p><span>分支程序设计</span></p><ul><li><p><span>在一个实际的程序中，程序始终是顺序执行的情况并不多见，通常都会有各种分支。具有两个或两个以上可选执行路径的程序叫做分支程序</span></p></li><li><p><span>使用带有条件码的指令可以很容易地实现分支程序</span></p></li><li><p><span>程序分支点上有多于两个以上的执行路径的程序叫做多分支程序（或散转）。利用条件测试指令或跳转表可以实现多分支程序</span></p></li><li><p><span>编写一个分支程序段，如果寄存器R5中的数据等于 10，就把 R5 中的数据存入寄存器 R1;否则把 R5 中的数据分别存入寄存器 R0 和 R1</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">;方法1：用条件指令实现</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">CMP</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">R5</span>，<span class="cm-comment">#10 &nbsp; </span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">MOVNE</span> &nbsp;<span class="cm-variable">R0</span>，<span class="cm-variable">R5</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">MOV</span> &nbsp; &nbsp; &nbsp; <span class="cm-variable">R1</span>，<span class="cm-variable">R5</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">;方法2：用转移指令实现</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">CMP</span> &nbsp; &nbsp; <span class="cm-variable">R5</span>，<span class="cm-comment">#10 &nbsp; </span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">BEQ</span> &nbsp; &nbsp; &nbsp;<span class="cm-keyword">doequal</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">MOV</span> &nbsp; &nbsp; <span class="cm-variable">R0</span>，<span class="cm-variable">R5</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-keyword">doequal</span> &nbsp;<span class="cm-keyword">MOV</span> &nbsp; &nbsp; <span class="cm-variable">R1</span>,<span class="cm-variable">R5</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 207px;"></div><div class="CodeMirror-gutters" style="display: none; height: 207px;"></div></div></div></pre></li></ul></li><li><p><span>编写一个程序段，当寄存器 R1 中的数据大于 R2 中数据时，将 R2 中的数据加 10 存入寄存器 R1;否则将 R2 中数据加 5 存入寄存器 R1</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">CMP</span> &nbsp; &nbsp; &nbsp; <span class="cm-variable">R1</span>，<span class="cm-variable">R2</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">ADDHI</span> &nbsp; <span class="cm-variable">R1</span>，<span class="cm-variable">R2</span>，<span class="cm-comment">#10</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">ADDLS</span> &nbsp; <span class="cm-variable">R1</span>，<span class="cm-variable">R2</span>，<span class="cm-comment">#5</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 69px;"></div><div class="CodeMirror-gutters" style="display: none; height: 69px;"></div></div></div></pre></li><li><p><span>注意条件码的设置：</span></p><ul><li><span>HI：无符号数大于，LS：无符号数小于或等于;</span></li><li><span>GT：有符号数大于，LE：带符号数小于或等于。</span></li></ul></li></ul></li><li><p><span>编写一个程序段，判断寄存器R1中数据是否为 10、15、12、22。如果是，则将R0 中的数据加 1;否则将 R0 设置为0xF</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">MOV</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">R0</span>，<span class="cm-comment">#0</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-keyword">TEQ</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">R1</span>，<span class="cm-comment">#10</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-keyword">TEQNE</span> &nbsp; &nbsp; &nbsp; <span class="cm-variable">R1</span>，<span class="cm-comment">#15</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-keyword">TEQNE</span> &nbsp; &nbsp; &nbsp; <span class="cm-variable">R1</span>，<span class="cm-comment">#12</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-keyword">TEQNE</span> &nbsp; &nbsp; &nbsp; <span class="cm-variable">R1</span>，<span class="cm-comment">#22</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-keyword">ADDEQ</span> &nbsp; &nbsp; &nbsp;<span class="cm-variable">R0</span>，<span class="cm-variable">R0</span>，<span class="cm-comment">#1</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-keyword">MOVNE</span> &nbsp; &nbsp; <span class="cm-variable">R0</span>，<span class="cm-comment">#0xF</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 161px;"></div><div class="CodeMirror-gutters" style="display: none; height: 161px;"></div></div></div></pre></li><li><p><span>ARM主要的条件测试指令：CMP  TEQ  TST CMN</span></p></li></ul></li><li><p><span>多分支散转程序设计</span></p><ul><li><p><span>当多分支程序的每个分支所对应的是一个程序段时，常常使用跳转地址表的方式来实现散转</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">MOV</span> &nbsp; <span class="cm-variable">R0</span>，N <span class="cm-comment">;N为表项序号0~2</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">ADR</span> &nbsp; <span class="cm-variable">R5</span>，JPTAB</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">LDR</span> &nbsp; <span class="cm-variable-2">PC</span>，[<span class="cm-variable">R5</span>，<span class="cm-variable">R0</span>，LSL <span class="cm-comment">#2]</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">JPTAB</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-comment">;跳转表 </span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp;<span class="cm-keyword">DCD</span> &nbsp; <span class="cm-keyword">FUN0</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp;<span class="cm-keyword">DCD</span> &nbsp; <span class="cm-keyword">FUN1</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp;<span class="cm-keyword">DCD</span> &nbsp; <span class="cm-keyword">FUN2</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">FUN0</span> &nbsp;  ….. &nbsp; <span class="cm-comment">;分支FUN0的程序段</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">FUN1</span> &nbsp;  ….. &nbsp; <span class="cm-comment">;分支FUN1的程序段</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">FUN2</span> &nbsp;  ….. &nbsp; <span class="cm-comment">;分支FUN2的程序段</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 230px;"></div><div class="CodeMirror-gutters" style="display: none; height: 230px;"></div></div></div></pre></li><li><p><span>或用B指令实现散转（带参数检查）：</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">CMP</span> &nbsp; &nbsp; &nbsp; <span class="cm-variable">R0</span>, <span class="cm-comment">#MAX INDEX </span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">ADDLO</span> &nbsp; <span class="cm-variable-2">PC</span>, <span class="cm-variable-2">PC</span>, <span class="cm-variable">R0</span>, LSL <span class="cm-comment">#2 </span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">BHI</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">ERROR</span> </span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">B</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">FUN0</span> &nbsp; &nbsp; </span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">B</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">FUN1</span> </span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">B</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">FUN2</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 138px;"></div><div class="CodeMirror-gutters" style="display: none; height: 138px;"></div></div></div></pre></li></ul></li></ul></li><li><p><span>带有状态切换的分支跳转</span></p><ul><li><p><span>若需要在程序跳转的同时还要进行处理器状态的转移，即从 ARM 指令程序段跳转到Thumb 指令程序段（或相反）</span></p></li><li><p><span>此时可使用系统专用的指令BX来实现（指令格式：BX Rm)</span></p><ul><li><span>跳转的rm高31位为地址给pc，低1位为t控制位，控制a/t指令</span></li></ul></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly" style="break-inside: unset;"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">;ARM 指令程序→ Thumb 指令程序</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ；ARM指令程序</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-keyword">CODE32</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  …..</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-keyword">ADR</span> &nbsp;<span class="cm-variable">R0</span>,Into_Thumb + 1</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-variable">BX</span> &nbsp; <span class="cm-variable">R0</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; …..</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-comment">;Thumb指令程序</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-keyword">CODE16</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Into_Thumb</span>  …….</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">;Thumb 指令程序→ ARM指令程序</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ； Thumb 指令程序</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-keyword">CODE16</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  …..</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-keyword">ADR</span> &nbsp;<span class="cm-variable">R0</span>,Back_to_ARM</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-variable">BX</span> &nbsp; <span class="cm-variable">R0</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; …..</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-comment">; ARM指令程序</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-keyword">CODE32</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Back_to_ARM</span> &nbsp; …….</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 460px;"></div><div class="CodeMirror-gutters" style="display: none; height: 460px;"></div></div></div></pre></li></ul></li><li><p><span>循环程序设计</span></p><ul><li><p><span>编写一个程序，把首地址为DATA_SRC 的 80 个字的数据复制到首地址为 DATA_DST 的目标数据块中</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">LDR</span> &nbsp; &nbsp;<span class="cm-variable">R1</span>，<span class="cm-tag">=DATA_SRC</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">LDR</span> &nbsp; &nbsp;<span class="cm-variable">R0</span>，<span class="cm-tag">=DATA_DST</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">MOV</span> &nbsp; &nbsp;<span class="cm-variable">R10</span>，<span class="cm-comment">#10</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">LOOP</span> &nbsp;<span class="cm-keyword">LDMIA</span> &nbsp;<span class="cm-variable">R1</span>！，<span class="cm-braket">{</span><span class="cm-variable">R2</span>-<span class="cm-variable">R9</span><span class="cm-braket">}</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp;<span class="cm-keyword">STMIA</span> &nbsp;<span class="cm-variable">R0</span>！，<span class="cm-braket">{</span><span class="cm-variable">R2</span>-<span class="cm-variable">R9</span><span class="cm-braket">}</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp;<span class="cm-keyword">SUBS</span> &nbsp; <span class="cm-variable">R10</span>，<span class="cm-variable">R10</span>，<span class="cm-comment">#1</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp;<span class="cm-keyword">BNE</span> &nbsp; &nbsp;<span class="cm-keyword">LOOP</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 161px;"></div><div class="CodeMirror-gutters" style="display: none; height: 161px;"></div></div></div></pre></li><li><p><span>编写一个程序，实现如下C语言程序功能。while（ x &lt;= y）x*= 2</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly" style="break-inside: unset;"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><span><span>​</span>x</span></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">;方法一</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">MOV</span> &nbsp; &nbsp; <span class="cm-variable">R0</span>, <span class="cm-comment">#1 </span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-keyword">MOV</span> &nbsp; &nbsp; <span class="cm-variable">R1</span>, <span class="cm-comment">#20 </span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-keyword">B</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">W_2</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">W_1</span> <span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-keyword">MOV</span> &nbsp; &nbsp; <span class="cm-variable">R0</span>, <span class="cm-variable">R0</span>, LSL <span class="cm-comment">#1 &nbsp; ；循环体</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">W_2</span> &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-keyword">CMP</span> <span class="cm-variable">R0</span>, <span class="cm-variable">R1</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ；判断条件</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-keyword">BLS</span> <span class="cm-keyword">W_1</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">W_END</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">;方法二</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">MOV</span> &nbsp; <span class="cm-variable">R0</span>, <span class="cm-comment">#1 </span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">MOV</span> &nbsp; <span class="cm-variable">R1</span>, <span class="cm-comment">#20 </span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">W_1</span><span class="cm-tab" role="presentation" cm-text="	"> </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-keyword">CMP</span> <span class="cm-variable">R0</span>, <span class="cm-variable">R1</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">BHI</span> &nbsp; <span class="cm-keyword">W_END</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">MOV</span> <span class="cm-variable">R0</span>, <span class="cm-variable">R0</span>, LSL <span class="cm-comment">#1 </span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">B</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">W_1</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">W_END</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 391px;"></div><div class="CodeMirror-gutters" style="display: none; height: 391px;"></div></div></div></pre></li></ul></li></ul></li><li><p><span>子程序设计</span></p><ul><li><p><span>任何一个大程序均可分解为许多相互独立的小程序，每个小程序完成特定的功能，相互之间通过子程序的方式来调用。并且，对于功能和结构形式都相同，只是某些变量的赋值不同的小程序，我们可以将其写成带参数的子程序形式</span></p></li><li><p><span>人们把可以多次反复调用的、能完成指定功能的程序段称为“子程序”。把调用子程序的程序称为“主程序”</span></p></li><li><p><span>为进行识别，子程序的第1条指令之前必须赋予一个标号，以便其他程序可以用这个标号调用子程序</span></p></li><li><p><span>子程序的调用和返回</span></p><ul><li><p><span>在 ARM 汇编语言程序中，主程序一般通过 BL 指令来调用子程序。该指令在执行时完成如下操作：将子程序的返回地址存放在链接寄存器LR中（不需要考虑流水线，处理器已做计算），同时将程序计数器PC指向子程序的入口点</span></p></li><li><p><span>为使子程序执行完毕能返回主程序的调用处，子程序末尾处应有 MOV、B、BX、LDMFD 等指令，并在指令中将返回地址重新复制到 PC 中（如MOV PC,LR 或B LR等）</span></p></li><li><p><span>在调用子程序的同时，也可以使用R0~R3 来进行参数的传递和从子程序返回运算结果。若参数超过4个，则使用堆栈来存放</span></p></li><li><p><span>编写一个子程序MAX，实现求两个数的最大值。再使用主程序去调用MAX</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly" style="break-inside: unset;"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">X</span> &nbsp; <span class="cm-keyword">EQU</span> <span class="cm-keyword">19</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">N</span> &nbsp;<span class="cm-keyword">EQU</span> <span class="cm-keyword">20</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; <span class="cm-keyword">AREA</span> <span class="cm-keyword">Example4</span>, CODE, READONLY </span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; <span class="cm-keyword">ENTRY</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; <span class="cm-keyword">CODE32</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">START</span> &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-keyword">LDR</span> &nbsp; &nbsp; <span class="cm-variable">R0</span>, <span class="cm-tag">=X</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">LDR</span> &nbsp; &nbsp;<span class="cm-variable">R1</span>, <span class="cm-tag">=N</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text="	">    </span> &nbsp;<span class="cm-keyword">BL</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">MAX</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">HALT</span> <span class="cm-tab" role="presentation" cm-text="	">   </span> &nbsp;<span class="cm-keyword">B</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">HALT</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">MAX</span> <span class="cm-tab" role="presentation" cm-text="	">    </span> &nbsp;<span class="cm-keyword">CMP</span> <span class="cm-variable">R0</span>, <span class="cm-variable">R1</span> </span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text="	">    </span> &nbsp;<span class="cm-keyword">MOVHI</span> <span class="cm-variable">R2</span>, <span class="cm-variable">R0</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text="	">    </span> &nbsp;<span class="cm-keyword">MOVLS</span> <span class="cm-variable">R2</span>, <span class="cm-variable">R1</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text="	">    </span> &nbsp;<span class="cm-keyword">MOV</span> <span class="cm-variable-2">PC</span>, <span class="cm-variable-2">LR</span> </span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">MAX_END</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; <span class="cm-keyword">END</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 368px;"></div><div class="CodeMirror-gutters" style="display: none; height: 368px;"></div></div></div></pre></li></ul></li></ul></li><li><p><span>子程序中堆栈的使用</span></p><ul><li><p><span>当子程序与主程序使用同一组寄存器时，为防止主程序的寄存器内容受到破坏，在子程序的开头应该把这些寄存器的数据压入堆栈以保护现场，在子程序返回之前需要把保护到堆栈中的数据弹出，恢复到原寄存器中，即恢复现场</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">relay</span> &nbsp; &nbsp; </span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; <span class="cm-tab" role="presentation" cm-text="	"> </span><span class="cm-keyword">STMFD</span> <span class="cm-variable-2">R13</span>!,<span class="cm-braket">{</span><span class="cm-variable">R4</span>-<span class="cm-variable">R12</span>,<span class="cm-variable-2">LR</span><span class="cm-braket">}</span><span class="cm-comment">;压入堆栈</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text="	">    </span> &nbsp; &nbsp;  …… &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-comment">;子程序代码</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text="	">    </span><span class="cm-keyword">LDMFD</span> <span class="cm-variable-2">R13</span>!,<span class="cm-braket">{</span><span class="cm-variable">R4</span>-<span class="cm-variable">R12</span>,<span class="cm-variable-2">PC</span><span class="cm-braket">}</span><span class="cm-comment">;弹出堆栈并返回</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 115px;"></div><div class="CodeMirror-gutters" style="display: none; height: 115px;"></div></div></div></pre></li></ul></li><li><p><span>访问外部标号</span></p><ul><li><p><span>当子程序需要引用另外一个文件定义的标号（如共享缓冲区）时，需要使用关键字 IMPORT 和 EXPORT。被引用的标号所在文件必须使用EXPORT或GLOBAL声明可以被外部已用。而引用该标号的文件必须使用IMPORT或EXTERN声明</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">; A.s文件</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; <span class="cm-keyword">AREA</span> <span class="cm-keyword">Buf</span>, DATA, READWRITE </span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; <span class="cm-keyword">EXPORT</span> <span class="cm-keyword">Var1</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Var1</span> &nbsp; <span class="cm-keyword">DCD</span> <span class="cm-keyword">0x12</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp;<span class="cm-keyword">END</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 115px;"></div><div class="CodeMirror-gutters" style="display: none; height: 115px;"></div></div></div></pre></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">; B.s文件</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; <span class="cm-keyword">AREA</span> <span class="cm-keyword">Example4</span>, CODE, READONLY </span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; <span class="cm-keyword">ENTRY</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; <span class="cm-keyword">CODE32</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; <span class="cm-keyword">IMPORT</span> <span class="cm-keyword">Var1</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Start</span> &nbsp; &nbsp; &nbsp;<span class="cm-keyword">LDR</span> <span class="cm-variable">R0</span>,<span class="cm-tag">=Var1</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-keyword">LDR</span> &nbsp;<span class="cm-variable">R1</span>,[<span class="cm-variable">R0</span>]</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-keyword">ADD</span> <span class="cm-variable">R1</span>,<span class="cm-variable">R1</span>,<span class="cm-comment">#1</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-keyword">STR</span> &nbsp; <span class="cm-variable">R1</span>,[<span class="cm-variable">R0</span>]</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp;<span class="cm-keyword">END</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 230px;"></div><div class="CodeMirror-gutters" style="display: none; height: 230px;"></div></div></div></pre></li></ul></li></ul><p>&nbsp;</p><h2><a name="arm汇编与c混合编程" class="md-header-anchor"></a><span>ARM汇编与C混合编程</span></h2><p>&nbsp;</p><h3><a name="概述-n2358" class="md-header-anchor"></a><span>概述</span></h3><ul><li><span>汇编不适合大工程，c语言便于理解，有大量的支持库，所以它是当前 ARM 程序设计所使用的主要编程语言</span></li><li><span>对硬件系统的初始化、CPU 状态设定、中断使能、主频设定以及 RAM 控制参数初始化等 C 程序力所不能及的底层操作，还是要由汇编语言程序来完成</span></li><li><span>对硬件系统的初始化、CPU 状态设定、中断使能、主频设定以及 RAM 控制参数初始化等 C 程序力所不能及的底层操作，还是要由汇编语言程序来完成</span></li><li><span>一个arm工程应由多个文件组成，包括汇编语言源文件、c/c++语言文件和c/c++头文件等</span></li></ul><h3><a name="arm工程" class="md-header-anchor"></a><span>ARM工程</span></h3><ul><li><p><span>各种源文件先由编译器和汇编器将它们分别编译或汇编成汇编语言文件及目标文件</span></p></li><li><p><span>链接器负责将所有目标文件连接成一个文件并确定各指令的确定地址，从而形成最终可执行文件</span></p></li><li><p><span>链接器有三个功能</span></p><ul><li><span>生成与地址相关的代码，把所有文件连接成一个可执行文件</span></li><li><span>根据程序员所指定的选项，为程序分配地址空间</span></li><li><span>给出链接信息，以说明链接过程和结果</span></li></ul></li><li><p><span>初始化阶段：汇编与C的衔接</span></p><ul><li><p><span>在ARM程序的初始化阶段，通常由汇编语言部分完成系统硬件的初始化，然后再使用跳转指令 B 或 BL进入C语言部分</span></p></li><li><p><span>ARM公司的开发环境ARM Developer Suite（简称ADS）定义的初始化阶段程序框架为</span></p><ul><li><span>运行汇编启动代码，并在最后调用_main</span></li><li><span>_main: C语言的初始化，并调用main</span></li><li><span>main: 主应用程序的入口点</span></li></ul></li><li><p><span>C与汇编之间的函数调用</span></p><ul><li><p><span>为了解决C和汇编的相互调用问题，此人们制定了 ARM-Thumb 过程调用标准 ATPCS</span></p></li><li><p><span>ATPCS 标准既是ARM的C编译器使用的函数调用规则，也是设计可被 C 程序调用的汇编函数的编写规则</span></p></li><li><p><span>函数是通过寄存器和堆栈来传递参数和返回函数值的。ATPCS 规定，ARM 的数据堆栈为 FD 型堆栈，即满递减堆栈。所以，堆栈的操作使用STMFD(push)和LDMFD(pop)</span></p></li><li><p><span>ATPCS 标准规定，对于参数个数不多于 4 的函数，编译器必须按参数在列表中的顺序，自左向右 为它们分配寄存器 R0~R3。其中函数返回时，R0 还被用来存放函数的返回值</span></p></li><li><p><span>如果函数的参数多于 4 个，那么多余的参数则按自右向左的顺序压入数据堆栈，即参数入栈顺序与参数顺序相反</span></p></li><li><p><span>编写一个C程序,调用如下汇编语言函数strcopy，实现字符串拷贝</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">AREA</span> <span class="cm-keyword">Strcopy</span>, CODE, READONLY</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">EXPORT</span> <span class="cm-keyword">strcopy</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">strcopy</span> &nbsp;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">LDRB</span> &nbsp;<span class="cm-variable">R2</span>,[<span class="cm-variable">R1</span>],<span class="cm-comment">#1</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">STRB</span> &nbsp;<span class="cm-variable">R2</span>,[<span class="cm-variable">R0</span>],<span class="cm-comment">#1</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">CMP</span> &nbsp;<span class="cm-variable">R2</span>,<span class="cm-comment">#0</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">BNE</span> &nbsp; <span class="cm-keyword">strcopy</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">MOV</span> <span class="cm-variable-2">PC</span>,<span class="cm-variable-2">LR</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">END</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 207px;"></div><div class="CodeMirror-gutters" style="display: none; height: 207px;"></div></div></div></pre></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="c"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="c"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">extern</span> <span class="cm-variable-3">void</span> <span class="cm-def">strcopy</span>(<span class="cm-variable-3">char</span> <span class="cm-variable-3">*</span><span class="cm-variable">d</span>, <span class="cm-keyword">const</span> <span class="cm-variable-3">char</span> <span class="cm-variable-3">*</span> <span class="cm-variable">s</span>);</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-variable-3">int</span> <span class="cm-def">main</span>(<span class="cm-variable-3">void</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> {</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; <span class="cm-keyword">const</span> <span class="cm-variable-3">char</span> <span class="cm-variable-3">*</span><span class="cm-variable">src</span> <span class="cm-operator">=</span> <span class="cm-variable">“source”</span>;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; <span class="cm-variable-3">char</span> <span class="cm-variable">dest</span>[<span class="cm-number">10</span>];</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; <span class="cm-variable">……</span>.</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; <span class="cm-variable">strcopy</span>(<span class="cm-variable">dest</span>, <span class="cm-variable">src</span>);</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; <span class="cm-variable">………</span>.</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> }</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 207px;"></div><div class="CodeMirror-gutters" style="display: none; height: 207px;"></div></div></div></pre></li></ul></li><li><p><span>编写一个汇编程序,调用如下C语言函数g，实现函数f的功能</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="c"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="c"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable-3">int</span> <span class="cm-def">g</span>(<span class="cm-variable-3">int</span> <span class="cm-variable">a</span>, <span class="cm-variable-3">int</span> <span class="cm-variable">b</span>, <span class="cm-variable-3">int</span> <span class="cm-variable">c</span>, <span class="cm-variable-3">int</span> <span class="cm-variable">d</span>, <span class="cm-variable-3">int</span> <span class="cm-variable">e</span>)</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">{</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">return</span> <span class="cm-variable">a</span><span class="cm-operator">+</span><span class="cm-variable">b</span><span class="cm-operator">+</span><span class="cm-variable">c</span><span class="cm-operator">+</span><span class="cm-variable">d</span><span class="cm-operator">+</span><span class="cm-variable">e</span>;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">}</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable-3">int</span> <span class="cm-def">f</span>(<span class="cm-variable-3">int</span> <span class="cm-variable">i</span>) </span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">{</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; <span class="cm-keyword">return</span> <span class="cm-variable">–g</span>(<span class="cm-variable">i</span>, <span class="cm-number">2</span><span class="cm-operator">*</span><span class="cm-variable">i</span>, <span class="cm-number">3</span><span class="cm-operator">*</span><span class="cm-variable">i</span>, <span class="cm-number">4</span><span class="cm-operator">*</span><span class="cm-variable">i</span>,<span class="cm-number">5</span><span class="cm-operator">*</span><span class="cm-variable">i</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">}</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 184px;"></div><div class="CodeMirror-gutters" style="display: none; height: 184px;"></div></div></div></pre></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly" style="break-inside: unset;"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">AREA</span> &nbsp; <span class="cm-keyword">f</span>,  CODE,  READONLY</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">IMPORT</span> &nbsp; <span class="cm-keyword">g</span> &nbsp; ；声名g为外部引用符号</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">f</span> &nbsp; &nbsp; &nbsp;<span class="cm-keyword">STR</span> &nbsp; <span class="cm-variable-2">LR</span>, &nbsp; [<span class="cm-variable">SP</span>, <span class="cm-comment">#-4]!  ；断点存入堆栈</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; <span class="cm-keyword">ADD</span> &nbsp;<span class="cm-variable">R1</span>, <span class="cm-variable">R0</span>, <span class="cm-variable">R0</span>  ；（<span class="cm-variable">R1</span>）<span class="cm-tag">=</span> i*2</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; <span class="cm-keyword">ADD</span> &nbsp;<span class="cm-variable">R2</span>, <span class="cm-variable">R1</span>, <span class="cm-variable">R0</span>  ；（<span class="cm-variable">R2</span>）<span class="cm-tag">=</span> i*3</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; <span class="cm-keyword">ADD</span> &nbsp;<span class="cm-variable">R3</span>, <span class="cm-variable">R1</span>, <span class="cm-variable">R2</span>  ；（<span class="cm-variable">R3</span>）<span class="cm-tag">=</span> i*5</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; <span class="cm-keyword">STR</span> &nbsp; <span class="cm-variable">R3</span>, [<span class="cm-variable">SP</span>, <span class="cm-comment">#-4]! ；将（R3）存入堆栈</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; <span class="cm-keyword">ADD</span> &nbsp;<span class="cm-variable">R3</span>, <span class="cm-variable">R1</span>, <span class="cm-variable">R1</span> ；（<span class="cm-variable">R3</span>）<span class="cm-tag">=</span> i*4</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; <span class="cm-keyword">BL</span> &nbsp;<span class="cm-keyword">g</span>  ；调用C函数g()，返回值在寄存器<span class="cm-variable">R0</span>中</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; <span class="cm-keyword">ADD</span> <span class="cm-variable">SP</span>, <span class="cm-variable">SP</span>, <span class="cm-comment">#4 ；清栈</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; <span class="cm-keyword">RSB</span> <span class="cm-variable">R0</span>, <span class="cm-variable">R0</span>, <span class="cm-comment">#0  ；返回值（R0）=0-（R0）</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; <span class="cm-keyword">LDR</span> <span class="cm-variable-2">PC</span>, [<span class="cm-variable">SP</span>],<span class="cm-comment">#4 &nbsp; ；恢复断点并返回</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; <span class="cm-keyword">END</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> </span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 322px;"></div><div class="CodeMirror-gutters" style="display: none; height: 322px;"></div></div></div></pre></li></ul></li><li><figure><table><thead><tr><th><span>寄存器</span></th><th><span>别名</span></th><th><span>用法</span></th></tr></thead><tbody><tr><td><span>R0~R3</span></td><td><span>A1~A4</span></td><td><span>参数和返回值寄存器（volatile）</span></td></tr><tr><td><span>R4~R8</span></td><td><span>V1~V5</span></td><td><span>函数局部变量寄存器（non-volatile）</span></td></tr><tr><td><span>R9</span></td><td><span>V6/sb</span></td><td><span>通用变量寄存器，在RWPI情况下保存静态基地址（non-volatile）</span></td></tr><tr><td><span>R10</span></td><td><span>V7/sl</span></td><td><span>通用变量寄存器，在使用堆栈边界检查的情况下用来保存堆栈边界地址（non-volatile）</span></td></tr><tr><td><span>R11</span></td><td><span>V8/fp</span></td><td><span>通用变量寄存器，在使用结构指针的情况下保存结构指针（non-volatile）</span></td></tr><tr><td><span>R12</span></td><td><span>IP</span></td><td><span>通用临时过渡寄存器，通常用于保存SP</span></td></tr><tr><td><span>R13</span></td><td><span>SP</span></td><td><span>堆栈指针</span></td></tr><tr><td><span>R14</span></td><td><span>LR</span></td><td><span>链接寄存器</span></td></tr><tr><td><span>R15</span></td><td><span>PC</span></td><td><span>程序计数器</span></td></tr></tbody></table></figure></li></ul></li><li><p><span>C与汇编之间的全局变量共享</span></p><ul><li><p><span>汇编程序如果要访问C语言中定义的全局变量，仍然需要使用IMPORT或EXTERN来声明</span></p></li><li><p><span>编写一个汇编代码的函数，引用一个在C文件中定义的整型全局变量globvar，将其加2后写回globvar</span></p><ul><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">AREA</span> <span class="cm-keyword">globals</span>, CODE, READONLY</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">EXPORT</span> &nbsp;<span class="cm-keyword">asmsubrouttine</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">IMPORT</span> &nbsp;<span class="cm-keyword">globvar</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Asmsubrouttine</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">LDR</span> &nbsp; &nbsp; <span class="cm-variable">R1</span>,<span class="cm-tag">=globvar</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">LDR</span> &nbsp; &nbsp; <span class="cm-variable">R0</span>,[<span class="cm-variable">R1</span>]</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-keyword">ADD</span> &nbsp; &nbsp; <span class="cm-variable">R0</span>,<span class="cm-variable">R0</span>,<span class="cm-comment">#2</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-keyword">STR</span> &nbsp; &nbsp; &nbsp;<span class="cm-variable">R0</span>,[<span class="cm-variable">R1</span>]</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-keyword">MOV</span> &nbsp; &nbsp;<span class="cm-variable-2">PC</span>,<span class="cm-variable-2">LR</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; <span class="cm-keyword">END</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 230px;"></div><div class="CodeMirror-gutters" style="display: none; height: 230px;"></div></div></div></pre></li></ul></li><li><figure><table><thead><tr><th><span>变量数据类型</span></th><th><span>对应的LDR/STR指令</span></th></tr></thead><tbody><tr><td><span>unsigned char</span></td><td><span>LDRB/STRB</span></td></tr><tr><td><span>unsigned short</span></td><td><span>LDRH/STRH</span></td></tr><tr><td><span>c</span></td><td><span>LDR/STR</span></td></tr><tr><td><span>signed char</span></td><td><span>LDRSB/STRSB</span></td></tr><tr><td><span>signed short</span></td><td><span>LDRSH/STRSH</span></td></tr><tr><td><span>小于8个字的结构型变量</span></td><td><span>LDM/STM</span></td></tr><tr><td><span>结构型变量的数据成员</span></td><td><span>使用相应的LDR／STR指令来访问，这时必须知道该数据成员相对于结构型变量开始地址的偏移量</span></td></tr></tbody></table></figure></li><li><p><span>C程序如果要访问汇编程序中定义且声明为可外部引用的数据，需要使用extern关键字来声明数据类型</span></p></li><li><p><span>编写一个C函数，引用一个如下汇编程序文件中定义的数据符号Var1，将赋值为0x20</span></p></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="assembly"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="assembly"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">; A.s文件</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp;<span class="cm-keyword">AREA</span> <span class="cm-keyword">Buf</span>, DATA, READWRITE </span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp;<span class="cm-keyword">EXPORT</span> <span class="cm-keyword">Var1</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">Var1</span> &nbsp; <span class="cm-keyword">DCD</span> <span class="cm-keyword">0x12</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp;<span class="cm-keyword">END</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 115px;"></div><div class="CodeMirror-gutters" style="display: none; height: 115px;"></div></div></div></pre></li><li><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="c"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="c"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 8px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">extern</span> <span class="cm-variable-3">int</span> <span class="cm-variable">Var1</span>;</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable-3">int</span> <span class="cm-def">main</span>(<span class="cm-variable-3">void</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">{</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">Var1</span> <span class="cm-operator">=</span> <span class="cm-number">0x20</span>;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">………</span>.</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">}</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 138px;"></div><div class="CodeMirror-gutters" style="display: none; height: 138px;"></div></div></div></pre></li></ul></li></ul></li></ul><h2><a name="soc嵌入式处理器系统" class="md-header-anchor"></a><span>SoC嵌入式处理器系统</span></h2><h3><a name="处理器存储器子系统" class="md-header-anchor"></a><span>处理器存储器子系统</span></h3><ul><li><p><span>SoC芯片内部的存储结构即称为处理器存储器子系统，ARM的处理器存储器子系统除了cache外，还可以包括：</span></p><ul><li><span>写缓存</span></li><li><span>紧耦合内存</span></li><li><span>内存管理/保护单元</span></li><li><span>协处理器</span></li></ul></li><li><p><span>Cache（高速缓存）：</span></p><ul><li><p><span>访问速度最快的本地内存，存放最近被访问过的内存副本。SoC中Cache全部都集成在嵌入式微处理器内，可分为：</span></p><ul><li><span>数据cache</span></li><li><span>指令cache</span></li><li><span>混合cache</span></li></ul></li><li><p><span>不同处理器cache大小不一样。一般32位SoC都内置cache</span></p></li></ul></li><li><p><span>Write buffer(写缓冲)</span></p><ul><li><span>减少写data到外部内存策树</span></li><li><span>data写道wb后。器控制逻辑自动将数据写到内存对应地址不需要cpu干预</span></li><li><span>wb较小，通常只有几十个字节</span></li></ul></li><li><p><span>TCM（紧耦合内存）</span></p><ul><li><span>一种快速的本地内存，对应了内存中特定的地址范围</span></li></ul></li><li><p><span>MMU（内存管理单元）</span></p><ul><li><p><span>控制内存的访问权限和内存区域的属性</span></p><ul><li><span>是否可被高数缓存</span></li><li><span>被缓存</span></li></ul></li><li><p><span>提供虚拟地址到物理地址的转换</span></p></li></ul></li><li><p><span>MPU（内存保护单元）</span></p><ul><li><span>弱化版mmu</span></li><li><span>控制内存访问权限、内存区域属性</span></li><li><span>不提供虚拟地址-》物理地址</span></li></ul></li></ul><p>&nbsp;</p><h3><a name="总线" class="md-header-anchor"></a><span>总线</span></h3><ul><li><p><span>AMBA总线</span></p><ul><li><span>一种总线规范，目前为3.0版本，是arm所采用的片内总线</span></li><li><span>快速设计出基于ARM CPU Core的芯片产品</span></li></ul></li><li><p><span>AMBA总线规范中，定义了3种总线</span></p><ul><li><p><span>AHB：</span></p><ul><li><span>用于高性能系统模块的链接，支持突发模式数据传输和事务分割；</span></li><li><span>可以有效地链接处理器、片上和片外存储器，支持流水线操作</span></li></ul></li><li><p><span>ASB</span></p><ul><li><span>也用于高性能系统模块的连接，较老的总线格式，现由AHB总线替代</span></li></ul></li><li><p><span>APB：</span></p><ul><li><span>用于较低性能外设的简单连接，一般是接在AHB或ASB系统总线上的第二级总线</span></li></ul></li></ul></li><li><p><span>AHB总线</span></p><ul><li><p><span>主单元：</span></p><ul><li><span>只有主单元可在任意时刻使用总线</span></li><li><span>AHB可以由一个或多个主单元</span></li><li><span>可以说RISC处理器、协处理器以及DMA控制器，以启动和控制总线操作</span></li></ul></li><li><p><span>从单元：</span></p><ul><li><span>可以响应（非启动）读/写总线操作</span></li><li><span>总线地从单元可以在给定地地址范围内对读写操作进行相应地反应</span></li><li><span>从单元向主单元发出成功、失败信号或等待各种反馈信号</span></li><li><span>从单元通常是其复杂程度不足以成为主单元地固定功能块，例如外存接口、总线桥接口以及任何内存都可以是从单元，系统地其他外设也包含在AHB的从单元中。</span></li></ul></li><li><p><span>仲裁器</span></p><ul><li><span>用来确定控制总线是哪个主单元，以保证在任何时候只有一个主单元可以启动数据传输</span></li><li><span>一般，仲裁协议都是固定好的，如最高优先级方法或平等方法，可根据实际的情况选择适当的仲裁协议</span></li></ul></li><li><p><span>总线译码器用于传输译码工作，提供传输过程中从单元的片选信号</span></p></li><li><p><span>工作过程包括两个阶段</span></p><ul><li><span>地址传送阶段(address phase)</span></li><li><span>数据传送阶段（data phase）</span></li></ul></li></ul></li><li><p><span>APB</span></p><ul><li><p><span>主要由2部分组成</span></p><ul><li><span>APB桥</span></li><li><span>APB从单元</span></li></ul></li><li><p><span>APB桥是APB中唯一的主单元，是AHB/ASB的从单元</span></p></li><li><p><span>APB桥将系统总线AHB/ASB和APB连接起来</span></p></li><li><p><span>APB从单元具有简单灵活的接口，接口的具体实现是依赖于特定设计的，有许多不同的可能</span></p></li></ul></li></ul><p>&nbsp;</p><h2><a name="嵌入式系统的片外存储系统" class="md-header-anchor"></a><span>嵌入式系统的片外存储系统</span></h2><p>&nbsp;</p><h3><a name="片外存储器" class="md-header-anchor"></a><span>片外存储器</span></h3><ul><li><span>ROM-NOR Flash, Nand Flash, EEPROM</span></li><li><span>RAM-RAM, SDRAM, DDR SDRAM</span></li><li><span>电子存储器-SD, MMC, xD, CF, MS</span></li><li><span>微硬盘</span></li></ul><h3><a name="ram" class="md-header-anchor"></a><span>RAM</span></h3><ul><li><p><span>SRAM</span></p><ul><li><span>SRAM的基本结构是一个双稳态电路</span></li><li><span>只要写电路不工作，电路就保持现状，不存在刷新的问题</span></li><li><span>读取操作对于SRAM不是破坏性的，所以SRAM不存在刷新的问题，存取速度快</span></li><li><span>因为价格比较昂贵，而且容量很小，所以SRAM一般作为系统内部的高速缓存或者某些处理器的外部扩展存储器 </span></li></ul></li><li><p><span>DRAM</span></p><ul><li><span>DRAM的速度比SRAM慢，但是由于结构比SRAM简单，所以相同容量的DRAM体积比SRAM小，所以价格便宜</span></li><li><span>DRAM 中存储的数据需要不断地刷新。存取速度相对SRAM较慢</span></li><li><span>早期主要用于显卡，声卡，硬盘等作为缓存，也用于PC系统作为主内存，由于速度和容量的原因，现在已经淘汰</span></li></ul></li><li><p><span>SDRAM/同步DRAM</span></p><ul><li><span>是广泛应用于计算机中的高速大容量存储器，在相当长时期内是存储器市场的主流</span></li><li><span>SDRAM在同步脉冲控制下工作，和微处理器共享一个时钟周期，在理论上可与微处理器外频同步</span></li><li><span>在嵌入式系统中目前应用非常广泛，是目前嵌入式系统的首选存储类型</span></li></ul></li><li><p><span>DDR SDRAM</span></p><ul><li><span>DDR 从它的英文名称Double Data Rate上面就能看出他的含义，简单的说就是双倍传输速率的SDRAM</span></li><li><span>理论上具有 SDRAM 内存两倍的带宽</span></li><li><span>DDR SDRAM目前已经普遍用于桌面PC系统作为主要内存使用，对速度和性能要求较高的嵌入式系统也开始采用DDR SDRAM作为内存。比如网络设备，音视频处理设备等</span></li></ul></li></ul><h3><a name="rom" class="md-header-anchor"></a><span>ROM</span></h3><ul><li><p><span>NOR Flash</span></p><ul><li><span>不需要改变电压就可以进行擦除，通常通过WP（Write protect，写保护）信号进行操作</span></li><li><span>具有EEPROM和RAM的特点，读写速度快，写入数据后断电不丢失</span></li><li><span>NOR flash因为可以直接执行代码，而且存取速度很快，一般用于嵌入式系统中存放引导程序和应用程序</span></li><li><span>NOR flash的组合应用与RAM类似，也可以根据系统需要，将8位的flash组合为16位或者32位使用</span></li></ul></li><li><p><span>NAND Flash</span></p><ul><li><span>优点：硬件接口简单，总共只需要10几根信号线，容量大，目前单片可以达到几个Gb，远远超过NOR flash，价格便宜，读写速度快</span></li><li><span>缺点：必须处理器的专用接口才能作为引导器件，存取方式相对复杂，芯片容易存在缺陷，一般需要采用ECC算法进行校验</span></li><li><span>擦除操作是以块为单位进行的</span></li><li><span>NAND flash因为其容量大，成本低，目前已广泛用于嵌入式产品中包括数码相机、MP3随身听记忆卡、体积小巧的U盘、以及固态硬盘等产品</span></li></ul></li><li><p><span>EPROM</span></p><ul><li><span>芯片可重复擦除和写入，解决了PROM芯片只能写入一次的弊端</span></li><li><span>EPROM内资料的写入要用专用的编程器，并且往芯片中写内容时必须要加一定的编程电压</span></li><li><span>EPROM早期主要作为处理器的外部扩展存储器以及PC上的BIOS存储器，但是因为要用紫外线通过特殊设备才能擦除，所以后续逐渐被EEPROM所取代</span></li></ul></li><li><p><span>EEPROM</span></p><ul><li><span>可以在系统/在线进行编程，也可以根据需要进行多次擦除和修改，数据写入之后即使断电也不会丢失。一般可反复擦写10万次左右</span></li><li><span>因为容量不是很大，所以EEPROM主要用于系统中存放引导程序、配置参数、需要修改的数据等</span></li></ul></li><li><p><span>FRAM</span></p><ul><li><span>铁电存储器（FRAM）是近年来新出现的一种读写速度非常快的存储器，它可以兼容RAM的一切功能，并且和ROM技术一样，是一种非易失性的存储器</span></li><li><span>一种非易失性的RAM</span></li><li><span>铁电存储器的读写速度更快。与其它存储器相比，铁电存储器写入时几乎不需要等待时间，而EEPROM一般需要几毫秒。读的速度同样也很快，和写操作在速度上几乎没有太大的区别</span></li><li><span>FRAM存储器几乎可以无限次擦写，而EEPROM则一般只能进行几十万次到100万次的擦写</span></li><li><span>FRAM主要用于对反复擦写次数要求高，读写速度快的场合</span></li></ul></li></ul><h2><a name="32位嵌入式系统常用总线" class="md-header-anchor"></a><span>32位嵌入式系统常用总线 </span></h2><ul><li><p><span>并行总线：数据线与数据位数相同</span></p><ul><li><span>信息的各位数据被同时传送的通信方式</span></li><li><span>所有数据位同时传送，传送速度快、效率高 </span></li><li><span>有多少数据位就要多少根数据线，硬件成本高</span></li><li><span>数据线越多，相互干扰越大 ，只适合近距离传输（几十厘米到几米范围）</span></li><li><span>EBI，IDE，SCSI，PCI等</span></li></ul></li><li><p><span>串行总线：不管数据位数是多少，一般只需要一根数据线</span></p><ul><li><span>信息的各位数据按照一定的顺序逐位进行传输的通信方式 </span></li><li><span>每次只能传输一位数据，传输速率依赖于传输的波特率</span></li><li><span>不论传输多少位数据，都只需要一根数据线，成本低</span></li><li><span>传输距离最远可达上千公里，如光纤通信</span></li><li><span>USB    IEEE1394   I2C   SPI   RS232  CAN  LIN等</span></li></ul></li></ul><h3><a name="pci总线" class="md-header-anchor"></a><span>PCI总线</span></h3><ul><li><p><span>特点</span></p><ul><li><span>地址、数据多路复用的高性能32位和64位总线</span></li><li><span>32位PCI 有120引脚，64 位有184 引脚</span></li><li><span>从数据宽度上看，PCI 总线有32bit 、64bit 之分</span></li><li><span>从总线速度上分，有33MHz、66MHz、133MHz</span>
<span>总线带宽为133MB/s到超过1GB/s</span></li><li><span>与ISA 总线不同，PCI 总线的地址总线与数据总线是分时复用的，支持即插即用(Plug and Play) 、中断共享等功能</span></li><li><span>分时复用的好处是一方面可以节省接插件的管脚数，另一方面便于实现突发数据传输</span></li><li><span>数据传输时，由一个PCI 设备做发起者(主控、Initiator或Master)，而另一个PCI 设备做目标(从设备、Target 或Slave)</span></li><li><span>PCI 总线在同一时刻只能供一对设备完成传输，这就要求有一个仲裁机构，来决定谁有权拿到总线的主控权</span></li></ul></li></ul><h3><a name="spi总线" class="md-header-anchor"></a><span>SPI总线</span></h3><ul><li><p><span>一种同步串行外设接口</span></p></li><li><p><span>通过SPI总线连接的设备可以同时发送和接收串行数据，它可以使MCU与各种外围设备以串行、同步的方式进行通信以交换信息</span></p></li><li><p><span>SPI的最高工作速率可以到20Mbps左右</span></p></li><li><p><span>接口信号：SPI的接口一般使用4根信号线</span></p><ul><li><span>串行时钟线（SCK）</span></li><li><span>主机输入/从机输出数据线MISO</span></li><li><span>主机输出/从机输入数据线MOSI</span></li><li><span>低电平有效的从机选择线SSx（x可为0,1,2……） </span></li></ul></li><li><p><span>基本传输原理：通过移位寄存器来完成的。</span></p><ul><li><span>简单的来理解，就像将两个寄存器贴在一起，然后进行循环左移或者循环右移（SPI 的传输可以选择先发送高位还是先发送低位），直到两个寄存器的数据交换为止。而时钟信号 SCLK 就是控制传输速率的</span></li></ul></li><li><p><span>工作时序</span></p><ul><li><span>写时序:当主机需要对从机进行写入操作时，主机首先将SS信号拉低，选中某个从机，与从机建立通信通道。然后主机通过MOSI发送写命令字节和寄存器地址字节，然后再发送数据字节，数据字节可以是一个或者多个 </span></li><li><span>读时序:当主机需要对从机进行读出操作时，主机首先将SS信号拉低，选中某个从机，与从机建立通信通道。然后主机通过MOSI发送读命令字节和寄存器地址字节，在SCK的驱动下，从机将数据从MISO上送出，直到停止SCK信号为止 </span></li></ul></li><li><p><span>状态标志</span></p><ul><li><p><span>发送缓冲器空闲标志(TXE)</span></p><ul><li><span>此标志为’1’时表明发送缓冲器为空，可以写下一个待发送的数据进入缓冲器中。当写入SPI_DR时，TXE标志被清除</span></li></ul></li><li><p><span>接收缓冲器非空(RXNE)</span></p><ul><li><span>此标志为’1’时表明在接收缓冲器中包含有效的接收数据。读SPI数据寄存器可以清除此标志</span></li></ul></li><li><p><span>忙(Busy)标志</span></p><ul><li><span>BSY标志由硬件设置与清除(写入此位无效果)，此标志表明SPI通信层的状态</span></li></ul></li></ul></li></ul><p>&nbsp;</p><h3><a name="i2c" class="md-header-anchor"></a><span>I2C</span></h3><ul><li><p><span>I2C(Inter－Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线，用于连接微控制器及其外围设备。I2C总线产生于80年代，最初是为音频和视频设备开发的</span></p></li><li><p><span>I2C总线最主要的优点是其简单性和有效性</span></p></li><li><p><span>由于接口简单，I2C总线占用的空间非常小，减少了电路板的空间需求和芯片引脚的数量，降低了互联成本</span></p></li><li><p><span>支持多主机(multimastering)模式，任何能够进行数据发送和接收的设备都可以成为主机</span></p></li><li><p><span>一个主机能够控制总线上信号的传输和时钟频率。当然，在任何一个时间只能有一个设备工作于主机模式</span></p></li><li><p><span>总线信号</span></p><ul><li><span>I2C总线由时钟信号SCL和双向数据信号SDA组成 </span></li></ul></li><li><p><span>工作原理</span></p><ul><li><span>开始信号: SCL为高电平时，SDA由高电平向低电平跳变，开始传送数据</span></li><li><span>结束信号: SCL为高电平时， SDA由低电平向高电平跳变，结束传送数据 </span></li></ul></li><li><p><span>总线工作原理</span></p><ul><li><p><span>总线上每次传送开始时有起始信号，结束时有停止信号</span></p></li><li><p><span>启动总线后第一个字节(命令字节)的高7位是从器件的寻址地址，其中最高4位为器件类型识别码，接着的3位为器件地址，第８位为方向位（“０”表示写操作，“１”表示读操作)</span></p></li><li><p><span>地址字节后面的字节为传输的数据,数据字节可以是1~n个</span></p></li><li><p><span>每个字节传输完成后，接收方必须发出一个应答位,用于确认接收方是否正确接收（发送方释放SDA保持高电平，接收方将其拉低表示一个应答，没有拉低则没有应答）</span></p></li><li><p><span>总线的数据传输采用最高位（MSB） 在前的方式</span></p></li><li><p><span>数据传输流程</span></p><ul><li><span>主机方需要通信时,首先产生一个起始信号,通知总线上的其他设备即将开始一个通信操作</span></li><li><span>主机然后在SCL的同步下发送一个命令字节,在接收到从机的应答信号后,再发送一个字节的寄存器地址</span></li><li><span>如果是写操作,后续则发送一个或多个字节的待写入数据到从机，直到主机产生一个停止信号，结束本次通信</span></li><li><span>如果是读操作，则在发送地址字节之后，主机将SDA置为输入状态，在SCL的驱动下，从机将数据送出到SDA上，直至主机产生停止信号</span></li></ul></li></ul></li></ul><p>&nbsp;</p><h3><a name="uart重点复习" class="md-header-anchor"></a><span>UART</span><em><span>重点复习</span></em></h3><ul><li><p><span>UART（Universal Asynchronous Receiver/Transmitter）即通用异步收发器，是嵌入式系统上很常用的一种串行接口，用于异步通信，可以实现全双工数据传输和接收</span></p></li><li><p><span>UART主要用于各种低速数据传输的场合，如控制台、modem等。UART工作于对等模式下，只要通信速率设置正确，UART接口两端的设备都可以自由发送数据。传输速率一般从1200bps到115200bps</span></p></li><li><p><span>根据应用环境的不同，UART接口可以转换为RS232、RS422或者RS485的工业标准与其他设备进行互联，来完成几十米至几公里距离上的数据传输</span></p></li><li><p><span>信号组成</span></p><ul><li><span>UART接口一般由</span><strong><span>9个信号</span></strong><span>组成，包括RD(数据输入)、TD(数据输出)、CTS(允许发送)、RTS(请求发送)、DTR(数据终端就绪)、CD(载波检测)、DSR(数据设备就绪)、RI(振铃指示)和GND（地线），也可以在某些应用场合采用更简单的</span><strong><span>3线制（只有RD、TD和GND信号）</span></strong><span>进行数据传输</span></li><li><span>DSR，数据设备就绪（Data set ready)。当该信号处于有效（ON）状态，表明MODEM处于可以使用的状态</span></li><li><span>DTR，数据终端就绪(Data Terminal ready)。当该信号处于有效（ON）状态，表明数据终端可以使用  </span></li><li><span>RTS，请求发送(Request to send)。用来表示DTE（数据终端设备）请求DCE（数据通信设备）发送数据，当终端需要发送数据时，使该信号有效（ON状态），向MODEM请求发送。它用来控制MODEM是否要进入发送状态 </span></li><li><span>CTS，允许发送（Clear to send ）。用来表示DCE准备好接收DTE发来的数据，是对请求发送信号RTS的响应信号。当MODEM已准备好接收终端传来的数据，并向前发送时，使该信号有效，通知终端开始向发送数据线TxD发送数据。RTS/CTS这对请求应答联络信号用于半双工MODEM系统中发送方式和接收方式之间的切换，在全双工系统中，因配置为双向通道，故不需要RTS/CTS联络信号，可以使其一直保持为高电平 </span></li><li><span>RLSD，接收线信号检出(Received Line detection)。用来表示DCE已接通通信链路，告知DTE准备接收数据。当本地的MODEM收到由通信链路另一端（远地）的MODEM送来的载波信号时，使RLSD信号有效，通知终端准备接收，并且由MODEM将接收下来的载波信号解调成数字数据后，通过接收数据线RxD送到终端。此线也叫做数据载波检测(Data Carrier dectection — DCD）线 </span></li><li><span>RI，振铃指示(Ringing)。当MODEM收到交换台送来的振铃呼叫信号时，使该信号有效（ON状态），通知终端已被呼叫 </span></li><li><strong><span>TxD，发送数据(Transmitted data)。通过TxD线，终端将串行数据发送到MODEM(DTE→DCE)</span></strong></li><li><strong><span>RxD，接收数据(Received data)。通过RxD线，终端接收从MODEM发来的串行数据(DCE→DTE)</span></strong></li><li><span>GND: 接地线</span></li></ul></li><li><p><span>工作原理</span></p><ul><li><span>UART工作采用异步模式，数据位可以设置为8位、9位和10位三种，停止位分为1位、1.5位和2位三种。因为没有时钟信号，所以需要双方约定好通信的格式和速率才能进行通信。接收方定时检查信号线上的电平变化来确定当前传输的数据位，从而接收完整的数据帧</span></li><li><span>在没有数据传输时TxD和RxD端都是高电平；当需要发送数据时，传输方就将TxD先置为低电平(起始位)，通知对方开始接收数据，然后按照预先设置好的波特率按从低位到高位的顺序发送数据位，最后将TxD置为高电平，产生结束位，从而结束一次通信过程 </span></li><li><span>UART是一种通用异步串行收发器，可以实现全双工传输。在嵌入式设计中，UART用来与PC及其他设备进行通信。 是TTL电平的串口</span></li></ul></li></ul><h3><a name="usb" class="md-header-anchor"></a><span>USB</span></h3><ul><li><p><span>通用串行总线”，是重要的串行接口之一</span></p></li><li><p><span>USB的目的在于将众多的接口（串口、并口、PS2口等），改为通用的标准</span></p></li><li><p><span>4针插头作为标准插头</span></p></li><li><p><span>采用主从模式，可以支持最多127个从机同时工作</span></p></li><li><p><span>支持热插拔</span></p></li><li><p><span>主机端会检测到从机接入的信号，然后主机会对从机进行相关的功能、特性配置。</span></p></li><li><p><span>配置完成后从机就可以根据主机的请求进行数据传输了</span></p></li><li><p><span>总线信号</span></p><ul><li><span>由差分数据线D+、D-和电源VCC、地GND四根信号线组成，D+，D-用于传送数据，VCC和GND用于向从机提供电源</span></li><li><span>USB总线接口的连接器分为A型和B型，A型用于Up-Stream 端口，也就是连接到主机的端口；B型则用于Down-Stream端口，也就是连接到设备的端口。另外还有一种小型连接器—MiniUSB，一般也用于设备端，以缩小连接器体积</span></li></ul></li><li><p><span>控制传输(Control Transfer)</span></p><ul><li><span>双向传送，数据量通常较小</span></li></ul></li><li><p><span>同步传输(Isochronous Transfer)</span></p><ul><li><span>确定的带宽和间隔时间</span></li><li><span>较强容错性的流数据传输</span></li><li><span>用于要求恒定的数据传送率的即时应用中</span></li><li><span>对于同步传送来说，即时的数据传递比完美的精度和数据的完整性更重要一些</span></li></ul></li><li><p><span>中断传输(Interrupt Transfer)</span></p><ul><li><span>定时查询设备是否有中断数据要传送</span></li><li><span>少量的分散的、不可预测数据的传输</span></li><li><span>单向的并且对于host来说只有输入的方式</span></li></ul></li><li><p><span>批量传输(Bulk Transfer)</span></p><ul><li><span>数据大量传送和接收、没有带宽和间隔时间要求的情况下，要求保证传输</span></li></ul></li></ul><p>&nbsp;</p><p>&nbsp;</p><h2><a name="嵌入式系统启动程序开发" class="md-header-anchor"></a><span>嵌入式系统启动程序开发</span></h2><h3><a name="板级初始化" class="md-header-anchor"></a><span>板级初始化</span></h3><ul><li><p><span>电复位后完成板级初始化工作。它具有完全的硬件特性，一般采用汇编语言实现</span></p></li><li><p><span>不同的嵌入式系统，板级初始化时要完成的工作具有一定的特殊性，但以下工作一般是必须完成的</span></p><ul><li><span>CPU中堆栈指针寄存器的初始化</span></li><li><span>BSS段(Block Storage Space)表示未被初始化的数据)的初始化</span></li><li><span>CPU芯片级的初始化：中断控制器、内存等的初始化</span></li></ul></li><li><p><span>CPU相关初始化</span></p><ul><li><span>CPU状态的初始化</span></li><li><span>协处理器的初始化</span></li></ul></li><li><p><span>Watchdog初始化</span></p></li><li><p><span>GPIO初始化</span></p></li><li><p><span>系统时钟初始化</span></p></li><li><p><span>内存初始化</span></p></li><li><p><span>模式初始化</span></p></li><li><p><span>中断向量初始化</span></p></li><li><p><span>MMU与Cache的初始化</span></p></li><li><p><span>语言相关初始化</span></p></li></ul><h3><a name="引导程序的3种情况重点" class="md-header-anchor"></a><span>引导程序的3种情况</span><em><span>重点</span></em></h3><ol start='' ><li><span>将软件从引导flash（通常是NOR Flash）中读取出来加载到RAM中运行，软件存储在flash中可以采用压缩存储的方式。这种方式的优点在于，压缩存储可以减少对flash空间的需求，降低成本，而在RAM中运行又可以提供比flash更快的速度</span></li><li><span>将软件从外存（如NandFlash、CF卡、MMC等）中读取出来加载到RAM中运行，采用这种方式获得更大的存储空间，成本更低，但是启动过程中软件加载的速度会慢一些</span></li><li><span>不将软件引导到RAM中而是让其直接在Nor Flash上运行，进入系统初始化阶段 </span></li></ol><h3><a name="从存储器中载入" class="md-header-anchor"></a><span>从存储器中载入</span></h3><ul><li><p><span>ROM/RAM: execute from ROM while using RAM for data, 使用RAM存放数据，在非易失性存储介质中执行代码</span></p><ul><li><img src=".\Embedded_8.png" referrerpolicy="no-referrer" alt="流程图"></li></ul><ol start='' ><li><span>复位时IP为内存中的第一条指令(复位向量)</span></li><li><span>复位向量跳转到boot loader .text的第一条指令</span></li><li><span>把boot loader的.data拷贝到RAM</span></li><li><span>为.bss分配存储空间</span></li><li><span>为stack分配存储空间</span></li><li><span>把SP置为stack的开始位置，boot完成</span></li><li><span>继续执行.text中的代码</span></li></ol></li><li><p><span>RAM: execute from RAM after being copied from ROM, and 在RAM中执行代码</span></p><ul><li><img src=".\Embedded_9.png" referrerpolicy="no-referrer" alt="流程图2"></li><li><span>1-6同上</span></li></ul><ol start='7' ><li><span>从ROM解压应用image，到RAM</span></li><li><span>-10. 把解压后的.txt、.data、.bss搬移到RAM中最终的位置</span></li><li><span>boot loader把控制权交给加载的image</span></li><li><span>释放Boot loader和临时存放解压image的空间</span></li></ol></li><li><p><span>execute from RAM after being downloaded from a host system. 代码从主机系统下载后，在RAM中执行</span></p><ul><li><img src=".\Embedded_10.png" referrerpolicy="no-referrer" alt="流程图3"></li><li><span>1-6:同上</span></li></ul><ol start='7' ><li><span>image从主机下载</span></li><li><span>完整性验证</span></li><li><span>-12）从RAM中，把下载的image拷贝到预定的位置</span></li><li><span>boot loader 把控制权交给image</span></li></ol></li></ul><p>&nbsp;</p><p>&nbsp;</p><h2><a name="嵌入式系统驱动软件开发" class="md-header-anchor"></a><span>嵌入式系统驱动软件开发</span></h2><h3><a name="设备接口寄存器概述" class="md-header-anchor"></a><span>设备接口寄存器概述</span></h3><ul><li><p><span>在与处理器核连接时，基本都提供了三类可以被处理器操作的寄存器</span></p><ul><li><p><span>控制寄存器：</span></p><ul><li><span>对设备的工作模式、工作时钟频率或数据传输速率、数据格式、中断使能或禁止等进行控制设置的寄存器，</span></li><li><span>一般设备初始化时进行设置，也可以在工作过程中修改，灵活。</span></li></ul></li><li><p><span>状态寄存器：</span></p><ul><li><span>包括设备在工作过程中的一些状态信息，这些信息可以被驱动软件使用，可以在合适时机更加设备状态进行对应操作，完成数据传输，错误处理等工作。</span></li><li><span>如果设备工作在中断方式下，状态寄存器中的某些标识与特定的中断相关联，也可以被中断处理程序加以利用</span></li></ul></li><li><p><span>数据寄存器：</span></p><ul><li><span>保存了需要通过设备向嵌入式系统外部发送的数据信息，或者从外部接收到的数据信息</span></li></ul></li></ul></li></ul><h3><a name="设备操作的基本原理" class="md-header-anchor"></a><span>设备操作的基本原理</span></h3><ul><li><p><span>从CPU Core参与数据传输过程的密切程度，设备操作可分为三种典型的模式</span></p><ul><li><p><span>轮循方式下CPU Core参与的密切程度最高，轮循时处理器不能进行其他工作</span></p></li><li><p><span>中断方式的密切程度次之</span></p><ul><li><span>中断未发生之前CPU core可以进行其他工作，当中断发生时再通过响应中断对设备进行相关操作，提高了处理器与设备工作的并行度</span></li><li><span>但中断的问题主要是：处理器在进行中断响应时需要一定的存储开销，并且有响应延迟</span></li></ul></li><li><p><span>DMA方式</span></p><ul><li><span>在需要连续的、大量的数据通信时</span></li><li><span>DMA是具有一定复杂性的总线主控设备</span></li><li><span>当采用DMA来完成设备之间、设备与内存之间的连续数据传输时，处理器对数据传输过程的参与密切程度是最低的</span></li><li><span>很大程度上提升了处理器与设备的并行性</span></li><li><span>DMA传输完成后也可以通过中断方式通知处理器进行下一步的处理</span></li></ul></li></ul></li></ul><p>&nbsp;</p><h3><a name="设备驱动开发需注意的问题" class="md-header-anchor"></a><span>设备驱动开发需注意的问题</span></h3><ul><li><p><span>可重入函数与互斥</span></p><ul><li><span>各种设备都是系统中的共享资源，设备驱动程序可能被各种运行的软件实体所调用，比如中断处理程序、任务或它们所调用的子函数，因此在编写驱动程序的时候需要考虑将来可能会在一个什么样的环境中使用这些设备，也就是说要考虑是否要编写可重入的驱动软件</span></li><li><span>可重入性是指函数可以被多个任务/线程调用</span></li><li><span>在多任务/线程系统中，函数是否具有可重入性是非常重要的，因为这是多个任务/线程可以共用此函数的必要条件</span></li></ul></li><li><p><span>可重入驱动函数</span></p><ul><li><span>编写可重入的驱动函数的一个重要原则是，如果使用全局变量、static变量，则应通过一定的互斥机制如关中断、信号量P/V操作等对其加以保护</span></li></ul></li><li><p><span>cache处理、缓冲和优化问题</span></p><ul><li><span>设备接口及其缓冲区是不能被处理器高速缓存和缓冲的，在对系统内存空间进行设置时，通常将I/O所映射的存储区域标识为非高速缓存(uncachable)和非缓冲（unbufferable)的，以强制处理器在每次访问时都去读外设端口，而不是从cache中读取陈旧的信息</span></li><li><span>在程序中通常会使用一些变量来实施对I/O端口的访问，这些变量是不能被编译器优化的，否则容易出现I/O端口操作数据的不一致性</span></li></ul></li></ul><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p></div>
</body>
</html>